鉴于Routeros的DDNS解析脚本不能提取返回Header，而华为DNS可以任意设置TTL，而华为目前没有完整API，因此借助了Cloudflare Worker，封装了一个API。视频链接：☺教程和文章更配哦~☺1、起因1、想要让DDNS解析快点，需要减小DNS系统的TTL2、常年使用DNSPOD，但是专业版DNSPOD更改TTL只能更改60，企业版才能改为13、想要不受服务器的限制2、技术分享首先需要你拥有一个Cloudflare的账号，没有可以注册一个创建worker2.1 点击创建服务2.2 增加一个服务名称，并创建服务2.3 快速编辑，复制代码，保存代码我会放到文末，需要的可以自取！！！创建完毕，点击发送，可以看到执行内容下面介绍一下如何使用通过GET提交方式，如下图所示，需要用到账户名、密码、zoneid、recordsetid、要更新IP地址、TTL信息相关信息获取教程在下面5. 附加内容华为云账户名获取1.1 在右上角，找到基本信息，点进去2.1 账号名就是华为云账户zoneid和recordsetid获取2.1 首先，找到你的域名，创建一个，如图所示2.2 点击F12，出现控制台，调整为Network栏2.3 修改值为某个IP，点击确定，搜索recordsets2.4 找到如下图的链接/** * Example someHost is set up to take in a JSON request * Replace url with the host you wish to send requests to * @param {string} url the URL to send the request to * @param {BodyInit} body the JSON data to send in the request */ //iam.ap-southeast-3.myhuaweicloud.com const someHost = 'https://iam.ap-southeast-3.myhuaweicloud.com'; //const someHost = 'https://iam.myhuaweicloud.com'; const url = someHost + '/v3/auth/tokens'; /** * gatherResponse awaits and returns a response body as a string. * Use await gatherResponse(..) in an async function to get the response body * @param {Response} response */ async function gatherResponse(response) { const { headers } = response; return headers.get('x-subject-token'); } async function handleRequest(request) { const { searchParams } = new URL(request.url); let name = searchParams.get('name'); let password = searchParams.get('password'); let hwZONEID = searchParams.get('zoneid'); let hwRECORDSETID = searchParams.get('recordsetid'); let hwip = searchParams.get('ip'); let ttl = searchParams.get('ttl'); let requestURL = new URL(request.url) let path = requestURL.pathname.split('/')[1]; if(name == null){ const ip = request.headers.get("cf-connecting-ip") return new Response("华为dns更新\n使用方法：https://"+request.url+"?name=华为云账户&password=华为云密码&zoneid=域名zoneid&recordsetid=域名recordsetid&ip=IP地址&ttl=生效时间\n当前ip:"+ip,{status: 200}); } console.log(name) const body = { "auth": { "identity": { "methods": ["password"], "password": { "user": { "name": name, "password": password, "domain": { "name": name } } } }, "scope": { "domain": { "name": name } } } }; const init = { body: JSON.stringify(body), method: 'POST', headers: { 'content-type': 'application/json;charset=UTF-8', }, }; const response = await fetch(url, init); const results = await gatherResponse(response); //return new Response(results, init); ddnsbody={ "records":[hwip], "ttl":ttl } ddnsinit = { body: JSON.stringify(ddnsbody), method: 'PUT', headers: { 'content-type': 'application/json;charset=UTF-8', 'X-Auth-Token': results }, }; //dns.ap-southeast-3.myhuaweicloud.com //ddnsurl='https://dns.myhuaweicloud.com/v2/zones/'+hwZONEID+'/recordsets/'+hwRECORDSETID ddnsurl='https://dns.ap-southeast-3.myhuaweicloud.com/v2/zones/'+hwZONEID+'/recordsets/'+hwRECORDSETID const myresponse = await fetch(ddnsurl, ddnsinit); return myresponse; return new Response(myresponse.text(), init); //return new Response(results, init); } addEventListener('fetch', event => { return event.respondWith(handleRequest(event.request)); });群晖支持代码1. 使用方法1.1 使用方法很简单，只需要把代码放到worker中，自定义DDNS服务提供商，填写下面内容，保存，如图所示：https://你的CLOUDFLARE WORKER地址/update?name=__USERNAME__&password=__PASSWORD__&zoneid=你的ZONEID&recordsetid=你的RECORDSETID&ip=__MYIP__&ttl=11.2 点击新增，选择服务提供商，填写下面内容即可/** * Example someHost is set up to take in a JSON request * Replace url with the host you wish to send requests to * @param {string} url the URL to send the request to * @param {BodyInit} body the JSON data to send in the request */ //iam.ap-southeast-3.myhuaweicloud.com const someHost = 'https://iam.ap-southeast-3.myhuaweicloud.com'; //const someHost = 'https://iam.myhuaweicloud.com'; const url = someHost + '/v3/auth/tokens'; /** * gatherResponse awaits and returns a response body as a string. * Use await gatherResponse(..) in an async function to get the response body * @param {Response} response */ async function gatherResponse(response) { const { headers } = response; return headers.get('x-subject-token'); } async function getresponse(response) { const { headers } = response; const contentType = headers.get('content-type') || ''; if (contentType.includes('application/json')) { return JSON.stringify(await response.json()); } return response.text(); } async function handleRequest(request) { const { searchParams } = new URL(request.url); let name = searchParams.get('name'); let password = searchParams.get('password'); let hwZONEID = searchParams.get('zoneid'); let hwRECORDSETID = searchParams.get('recordsetid'); let hwip = searchParams.get('ip'); let ttl = searchParams.get('ttl'); let requestURL = new URL(request.url) let path = requestURL.pathname.split('/')[1]; if(name == null){ const ip = request.headers.get("cf-connecting-ip") return new Response("华为dns更新\n使用方法：https://"+request.url+"?name=华为云账户&password=华为云密码&zoneid=域名zoneid&recordsetid=域名recordsetid&ip=IP地址&ttl=生效时间\n当前ip:"+ip,{status: 200}); } console.log(name) const body = { "auth": { "identity": { "methods": ["password"], "password": { "user": { "name": name, "password": password, "domain": { "name": name } } } }, "scope": { "domain": { "name": name } } } }; const init = { body: JSON.stringify(body), method: 'POST', headers: { 'content-type': 'application/json;charset=UTF-8', }, }; const response = await fetch(url, init); const results = await gatherResponse(response); //return new Response(results, init); ddnsbody={ "records":[hwip], "ttl":ttl } ddnsinit = { body: JSON.stringify(ddnsbody), method: 'PUT', headers: { 'content-type': 'application/json;charset=UTF-8', 'X-Auth-Token': results }, }; //dns.ap-southeast-3.myhuaweicloud.com //ddnsurl='https://dns.myhuaweicloud.com/v2/zones/'+hwZONEID+'/recordsets/'+hwRECORDSETID ddnsurl='https://dns.ap-southeast-3.myhuaweicloud.com/v2/zones/'+hwZONEID+'/recordsets/'+hwRECORDSETID const myresponse = await fetch(ddnsurl, ddnsinit); //return myresponse; const rcode=await getresponse(myresponse); console.log(rcode); if(JSON.parse(rcode)['error_code']=='APIGW.0301'){ return new Response("badauth", init); } if(JSON.parse(rcode)['code']=='DNS.0302'){ return new Response("nohost", init); } if(JSON.parse(rcode)['code']=='DNS.0313'){ return new Response("nohost", init); } if(JSON.parse(rcode)['code']=='DNS.0308'){ return new Response("abuse", init); } //return rcode; //return new Response(myresponse.body, init); //good return new Response("good", init); //return new Response(results, init); } addEventListener('fetch', event => { return event.respondWith(handleRequest(event.request)); });另附PHP版<?php function PostMain($url,$data){ $curl = curl_init(); curl_setopt($curl, CURLOPT_URL,$url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_POST,1); curl_setopt($curl, CURLOPT_POSTFIELDS,$data); curl_setopt($curl, CURLOPT_HEADER, true); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); $data = curl_exec($curl); curl_close($curl); $arr = explode("\r\n", $data); $token = explode(":", $arr[9]); return $token[1]; } function PutMeth($url,$data,$token){ $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json','X-Auth-Token: '.$token)); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT'); curl_setopt($ch, CURLOPT_POSTFIELDS,$data); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); curl_close($ch); return $response; } function codeecho($jsoncode,$domain_name){ if(isset($jsoncode['error_code'])){ if($jsoncode['error_code']=='APIGW.0301'){ return "badauth"; } } if(isset($jsoncode['code'])){ if($jsoncode['code']=='DNS.0302'){ return "nohost"; } if($jsoncode['code']=='DNS.0313'){ return "nohost"; } if($jsoncode['code']=='DNS.0308'){ return "abuse"; } } if($jsoncode['name']!=$domain_name."."){ return "nochg"; } return "good"; } function ddns($name,$password,$hwip,$ttl,$zoneid,$recordsetid,$domain_name){ $url = "https://iam.myhuaweicloud.com/v3/auth/tokens"; $ddnsurl="https://dns.myhuaweicloud.com/v2/zones/".$zoneid."/recordsets/".$recordsetid; $loginbody="{\"auth\":{\"identity\":{\"methods\":[\"password\"],\"password\":{\"user\":{\"name\":\"".$name."\",\"password\":\"".$password."\" ,\"domain\":{\"name\":\"".$name."\"}}}},\"scope\":{\"domain\":{\"name\":\"".$name."\"}}}}"; $ddnsbody="{\"records\":[\"$hwip\"],\"ttl\":".$ttl."}"; $token=PostMain($url,$loginbody); $result= PutMeth($ddnsurl,$ddnsbody,$token); $jsoncode=json_decode($result,true); return codeecho($jsoncode,$domain_name); } function usage(){ echo " 华为dns更新 使用方法： http://域名/update.php?name=华为云账户&password=华为云密码&zoneid=域名zoneid&recordsetid=域名recordsetid&ip=IP地址&ttl=生效时间&domain=域名 "; } header("Content-Type: text/html; charset=utf-8"); $myip=$_SERVER["REMOTE_ADDR"]; if (is_array($_GET) && count($_GET) > 0) { if (isset($_GET['name']) && isset($_GET['name']) && isset($_GET['password']) && isset($_GET['ttl']) && isset($_GET['zoneid']) && isset($_GET['recordsetid']) && isset($_GET['domain'])) { $name = $_GET['name']; $password=$_GET['password']; if(!isset($_GET['ip'])){ $_GET['ip']=$myip; } //$_GET['ip']=$myip; $hwip= $_GET['ip']; $ttl= $_GET['ttl']; $zoneid= $_GET['zoneid']; $recordsetid= $_GET['recordsetid']; $domain_name=$_GET['domain']; echo ddns($name,$password,$hwip,$ttl,$zoneid,$recordsetid,$domain_name); }else{ usage(); echo $myip; } }else{ usage(); echo $myip; } ?>思路参考的大佬的，在此感谢直达链接https://github.com/lllvcs/huaweicloud_ddns
前几天想要把服务器中远程ip分配给家里的某台服务器使用，因此写了这个教程记录一下过程。传统的frp、ngrok虽然可以达到内网穿透的效果，但是对于全端口映射是非常不方便的，因此想到使用Wireguard和RouterOS将服务器的ip分配给本地的方案。参考这个大佬的链接：https://aoyouer.com/posts/wireguard-l3-forward/主要分为以下几个过程：1、开启net.ipv4.ip_forward2、安装wireguard3、配置wireguard服务端4、更改ssh端口5、routeros配置wireguard6、添加路由规则7、测试1、开启net.ipv4.ip_forwardecho "net.ipv4.ip_forward=1">>/etc/sysctl.conf sysctl -p2、安装wireguardapt install wireguard iptables -y #安装wireguard modprobe wireguard && lsmod | grep wireguard #验证安装是否成功2、配置wireguard服务端公钥私钥生产cd /etc/wireguard # 首先进入配置文件目录 wg genkey | tee sprivatekey | wg pubkey > spublickey wg genkey | tee cprivatekey | wg pubkey > cpublickey #生成公钥和私钥服务端配置echo "[Interface] # 服务器的私匙，对应客户端配置中的公匙（自动读取上面刚刚生成的密匙内容） PrivateKey = $(cat sprivatekey) # 本机的内网IP地址，一般默认即可，除非和你服务器或客户端设备本地网段冲突 Address = 192.168.145.1/24 PostUp = iptables -t nat -A PREROUTING -d 10.0.24.11 -p tcp -m multiport --dports 65533,65534 -j ACCEPT; iptables -t nat -A PREROUTING -d 10.0.24.11 -p udp -m multiport --dports 65533,65534 -j ACCEPT; iptables -t nat -A PREROUTING -d 10.0.24.11 -j DNAT --to-destination 10.10.0.34; iptables -t nat -A POSTROUTING -s 10.10.0.34 -j SNAT --to-source 10.0.24.11; #10.0.24.11替换为你自己的网卡地址 65533为ssh端口 65534为wireguard端口 PostDown = iptables -t nat -D PREROUTING -d 10.0.24.11 -p tcp -m multiport --dports 65533,65534 -j ACCEPT; iptables -t nat -D PREROUTING -d 10.0.24.11 -p udp -m multiport --dports 65533,65534 -j ACCEPT; iptables -t nat -D PREROUTING -d 10.0.24.11 -j DNAT --to-destination 10.10.0.34; iptables -t nat -D POSTROUTING -s 10.10.0.34 -j SNAT --to-source 10.0.24.11; #10.0.24.11替换为你自己的网卡地址 # 服务端监听端口，可以自行修改 ListenPort = 65534 # 保持默认 MTU = 1420 # [Peer] 代表客户端配置，每增加一段 [Peer] 就是增加一个客户端账号。 [Peer] # 该客户端账号的公匙，对应客户端配置中的私匙 PublicKey = $(cat cpublickey) # 该客户端账号的内网IP地址 AllowedIPs = 192.168.145.0/24,10.10.0.0/16"|sed '/^#/d;/^\s*$/d' > wg0.conf修改ssh端口vim /etc/ssh/sshd_config 修改 Port 22 改为 Port 65533 systemctl restart sshd服务端启动wg-quick up wg04、routeros配置wireguardecho "[Interface] # 客户端的私匙，对应服务器配置中的客户端公匙（自动读取上面刚刚生成的密匙内容） PrivateKey = $(cat cprivatekey) # 客户端的内网IP地址 Address = 10.0.0.2/24 # 解析域名用的DNS DNS = 8.8.8.8 # 保持默认 MTU = 1420 [Peer] # 服务器的公匙，对应服务器的私匙（自动读取上面刚刚生成的密匙内容） PublicKey = $(cat spublickey) # 服务器地址和端口 Endpoint = X.X.X.X:443 # 因为是客户端，所以这个设置为全部IP段即可 AllowedIPs = 0.0.0.0/0, ::0/0 # 保持连接 PersistentKeepalive = 25"|sed '/^#/d;/^\s*$/d' > client.conf在routeros终端中输入以下内容interface/wireguard/add name="wireguard1" mtu=1300 private-key="你的interface私钥" /interface/wireguard/peers/add interface="wireguard1" public-key="你的peers公钥" endpoint-address="服务端ip" endpoint-port=端口 allowed-address="0.0.0.0/0" persistent-keepalive=5 /ip/address/add address="wireguard网卡网段" interface="wireguard1" routing/table/add name="wgt" fib /ip/route/add dst-address="0.0.0.0/0" gateway="wireguard1" routing-table="wgt" /routing/rule/add src-address="本地目标主机" routing-mark=main action=lookup-only-in-table table=wgt /ip/firewall/nat/add chain="srcnat" action=masquerade如下图为正常ping值如下图为通过wireguard把ip分配给本地延迟可以看到延迟增加了一倍，因此最好大家使用离自己区域进的地方使用。由于使用的是腾讯云8M轻量，因此测试带宽只有8M，算是把服务器网速跑满了。
分享一个自己写的DNSPOD DDNS ipv6脚本1、脚本分享#!/bin/bash DNSPOD_ID='你申请的DNSPOD ID' # DNSPOD 域名ID DNSPOD_PASSWORD='你的DNSPOD TOKEN' # DNSPOD Token RECORD_ID='域名RECORD_ID' #DNSPOD TOKEN ID SUB_DOMAIN='域名前缀' # SUB DOMAIN DOMAIN='域名后缀' # DOMAIN dns='2400:3200::1' check_ipv6_connect(){ check_connect=$(ping6 -w 3 240c::6666 -c 1 | grep ttl) if [ "$check_connect" == "" ] then echo "connect error" sleep 2 systemctl restart networking sleep 2 dhclient exit 1 fi } source /etc/profile check_ipv6_connect ipv6ustc=$(dig @240C::6666 AAAA test6.ustc.edu.cn +short) a=$(curl -s -H 'Host:test6.ustc.edu.cn' http://[$ipv6ustc]/backend/getIP.php | awk -F '"' '{print $4}') b=$(curl -s -X POST https://dnsapi.cn/Record.Info -d 'login_token='$DNSPOD_ID','$DNSPOD_PASSWORD'&format=json&domain='$DOMAIN'&record_id='$RECORD_ID'' |awk -F '"' '{print $60}') if [ "$a" != "$b" ] then curl -X POST https://dnsapi.cn/Record.Modify -d 'login_token='$DNSPOD_ID','$DNSPOD_PASSWORD'&format=json&domain='$DOMAIN'&record_id='$RECORD_ID'&sub_domain='$SUB_DOMAIN'&value='$a'&record_type=AAAA&record_line_id=0' echo "changed" else echo "no change" fi echo "success"2、参数说明DNSPOD_ID、DNSPOD_PASSWORD：点我进入DNSPOD密钥地址，创建密钥，如图所示：这两个参数填上RECORD_ID获取需要你的打卡域名解析记录，如图所示需要你使用先新建你的域名，例如blog.8086k.cn接下来打开F12，并切换到network选项按照图上方法操作可以看到两条记录，点开，如下操作添加上即可。SUB_DOMAIN:域名前缀 例如你的域名 blog.8086k.cn，那么SUB_DOMAIN就是blogDOMAIN:域名后缀 例如你的域名 blog.8086k.cn，那么DOMAIN就是8086k.cn3、使用方法放入到linux系统中，crontab中即可*/1 * * * * /root/ipv6.sh
本文主要介绍openwrt打包成lxc模板，并启动。1、LXC是什么[collapse title="LXC介绍" status="true"]Linux Container容器是一种内核虚拟化技术，可以提供轻量级的虚拟化，以便隔离进程和资源。[/collapse]2、openwrt介绍[collapse title="openwrt介绍" status="true"]OpenWrt是适合于嵌入式设备的一个Linux发行版。相对原厂固件而言，OpenWrt不是一个单一、静态的固件，而是提供了一个可添加软件包的可写的文件系统。这使用户可以自由的选择应用程序和配置，而不必受设备提供商的限制，并且可以使用一些适合某方面应用的软件包来定制你的设备。对于开发者来说，OpenWrt是一个框架，开发者不必麻烦地构建整个固件就能得到想要的应用程序；对于用户来说，这意味着完全定制的能力，与以往不同的方式使用设备，OPKG包含超过3500个软件。 默认使用LuCI作为web交互界面。[/collapse]3、LXC安装安装非常简单，apt即可。apt-get install bridge-utils apt-get install lxc lxc-checkconfig apt-get install apparmor-profiles4、配置首先桥接网卡在/etc/network/interfaces文件中添加br0网桥# /etc/network/interfaces auto br0 iface br0 inet static address ipv4地址 netmask ipv4子网掩码 bridge_ports 桥接网卡名 bridge_stp off bridge_fd 2 bridge_maxwait 20 iface br0 inet6 static address ipv6地址/120 gateway ipv6网关 dns-nameservers ipv6dns配置lxc默认文件在/etc/lxc/default.conf中添加如下内容#/etc/lxc/default.conf lxc.apparmor.profile = generated lxc.apparmor.allow_nesting = 1 lxc.net.0.type=veth lxc.net.0.link = br0 lxc.net.0.flags = up lxc.net.0.hwaddr = 00:11:22:xx:xx:xx5、使用创建镜像模板lxc-create -t download -n openwrt -- --no-validate --server mirrors.tuna.tsinghua.edu.cn/lxc-images启动容器lxc-start -n ubuntu1 -d停止容器lxc-stop --name ubuntu1销毁容器lxc-destroy --name ubuntu16、openwrt镜像制作首先下载你心仪的openwrt系统在linux下解压，使用如下命令gzip -d openwrt-x86-64-generic-squashfs-rootfs.img.gz解压之后出现openwrt-x86-64-generic-squashfs-rootfs.img文件安装squashfs-toolsapt install squashfs-tools解包会解压到squashfs-root目录进入 cd squashfs-rootunsquashfs openwrt-x86-64-generic-squashfs-rootfs.img mv squashfs-root rootfs解包后如图所示：这样lxc的rootfs就制作好了制作openwrt模板1、在/var/lib/lxc新建openwrt目录,mkdir /var/lib/lxc/openwrt touch /var/lib/lxc/openwrt/config2、把以下内容写入到config中# Template used to create this container: /usr/share/lxc/templates/lxc-download # Parameters passed to the template: --server mirrors.tuna.tsinghua.edu.cn/lxc-images # Template script checksum (SHA-1): 273c51343604eb85f7e294c8da0a5eb769d648f3 # For additional config options, please look at lxc.container.conf(5) # Uncomment the following line to support nesting containers: #lxc.include = /usr/share/lxc/config/nesting.conf # (Be aware this has security implications) # Distribution configuration lxc.include = /usr/share/lxc/config/common.conf lxc.arch = x86_64 # Container specific configuration lxc.apparmor.profile = generated lxc.apparmor.allow_nesting = 1 lxc.rootfs.path = dir:/var/lib/lxc/openwrt/rootfs lxc.uts.name = openwrt # Network configuration lxc.net.0.type=veth lxc.net.0.link = br0 lxc.net.0.flags = up lxc.net.0.hwaddr = 00:16:3e:35:10:cd接下来可以启动openwrt启动openwrtlxc-start -n openwrt -d配置openwrt系统使用lxc-attach进入openwrt系统vim /etc/config/network按照以下内容更改即可，这里做一个范例：config interface 'loopback' option ifname 'lo' option proto 'static' option ipaddr '127.0.0.1' option netmask '255.0.0.0' config globals 'globals' option ula_prefix 'fd8c:255f:3d91::/48' option packet_steering '1' config interface 'lan' option ifname 'eth0' option proto 'static' option ipaddr 'ipv4地址' option netmask 'ipv4掩码' option gateway 'ipv4网关' option dns 'DNS' config interface 'lan6' option proto 'static' option ifname '@lan' option ip6addr 'ipv6地址/120' option ip6gw 'ipv6网关' option delegate '0'【注】其他的配置参数，可以参考openwrt ipv6配置报错以及解决有可能openwrt系统stop之后会出现以下错误lxc-start: mylxc: conf.c: lxc_setup_ttydir_console: 1831 Read-only file system - Failed to set mode "0110" to "/dev/pts/3"解决方法：mount -o remount,rw /dev/ptslxc常用使用命令6.1 lxc开机启动命令### 修改容器配置文件，添加如下内容 ### lxc.start.auto = 1 ### lxc.start.delay = 15 ### lxc.group = onboot ### 第一项表示开启自启动，第二项表示启动延迟，第三项表示自启动顺序 # vim /var/lib/var/lib/lxc/<container-name>/config ### 自启动onboot组的容器 # lxc-autostart -g onboot6.2 lxc开启tun设备在/var/lib/lxc/你的容器下/目录下创建如下脚本：#!/bin/bash cd ${LXC_ROOTFS_MOUNT}/dev mkdir net mknod net/tun c 10 200 chmod 0666 net/tun赋予可执行权限chmod +x autodev最后，在容量的config文件最后，添加以下内容:lxc.hook.autodev=/var/lib/lxc/yourcontainer/autodev # /dev/net/tun lxc.cgroup.devices.allow = c 10:200 rwm重启动容器后，出现/dev/net/tun设备文件，需要tun设备的程序就可以执行了。最后放一张截图
自我折腾记录，校园网接入Padavan路由器没有ipv6，因此如果想要内网拥有IPV6，那么此教程正好适合你。1. 配置IPV6首先padavan设置需要这么设置，把IPV6打开，自动获取IPV6地址2. 配置脚本添加以下脚本到自定义设置->脚本->在路由器启动后执行的最后一行，如图所示modprobe ip6table_mangle ebtables -t broute -A BROUTING -p ! ipv6 -j DROP -i eth2.2 brctl addif br0 eth2.23. 重启电脑，IPV6就可以连上了。[scode type="blue"]参考博客：https://www.jianshu.com/p/ed34cbf3b90c[/scode]
本文主要内容是打包arm的spk文件,为以后自己方便查阅。一、nps介绍[collapse title="nps介绍" status="true"]nps是一款轻量级、高性能、功能强大的内网穿透代理服务器。balabala...具体详情请见github作者地址[/collapse]二、起因[scode type="yellow"]发现nps作者github下又群晖的安装包，但是是x86的，想着自己有个扎矿猫盘刷了群晖，是arm架构的，那么没办法，自己编译吧。-_-自己动手丰衣足食.jpg[/scode]三、逐渐的看代码过程。。。pass本次关键：从nps项目下的build.sh脚本看出来怎么部署，那么就按照build.sh脚本来吧废话不说了 进入正题吧四、正题开始4.1 部署环境[scode type="blue"]首先安装docker，安装过程pass，不会的请参照本博客其他帖子。[/scode]4.2 下载nps、docker镜像、spksrcroot@server:~# mkdir WorkShop #新建工作目录 root@server:~/WorkShop# https://github.com/ehang-io/nps.git # git clone nps项目 root@server:~/WorkShop# git clone https://github.com/cnlh/spksrc.git ~/WorkShop/spksrc # git clone spksrc项目 root@server:~/WorkShop# mkdir ~/WorkShop/spksrc/nps && cp -rf /root/WorkShop/nps/* ~/WorkShop/spksrc/nps/ # 拷贝文件 root@server:~/WorkShop/nps# docker pull synocommunity/spksrc #拉取镜像 有点大-_- root@server:~/WorkShop/nps# docker run -itd --name spksrc --env VERSION=0.26.6 -e GOPROXY=direct -v ~/WorkShop/spksrc:/spksrc synocommunity/spksrc /bin/bash # 运行容器 root@server:~/WorkShop/nps# docker exec -it spksrc /bin/bash -c 'cd /spksrc && make setup && cd /spksrc/spk/npc && make' # a few moments later... # 先试着编译X86的 没问题进行下一步[scode type="blue"]到这里有两种方法，一种简单点，另一种需要改Makefile文件[/scode][scode type="red"]第一种方法[/scode]root@server:~/WorkShop/nps# docker exec -it spksrc /bin/bash -c 'cd /spksrc/spk/npc && make clean && cd /spksrc && make setup && cd /spksrc/spk/npc && make arch-aarch64' # 直接加架构，编译成功 #可以直接把~/WorkShop/spksrc/packages/里的spk文件复制出来直接用了[scode type="red"]第二种方法[/scode]#更改Makefile root@server:~/WorkShop/spksrc/spk/npc# pwd /root/WorkShop/spksrc/spk/npc[scode type="blue"]把47行左右改为[/scode]ifeq ($(findstring $(ARCH),armada37xx),$(ARCH)) GO_ARCH = arm64 endif[scode type="blue"]之后执行一下代码，同样可以编译成功[/scode]root@harbor:~/WorkShop/spksrc/spk/npc# docker exec -it spksrc /bin/bash -c 'cd /spksrc/spk/npc && make clean && cd /spksrc && make setup && cd /spksrc/spk/npc && make arch-armada37xx-6.2' root@harbor:~/WorkShop/spksrc/packages# pwd /root/WorkShop/spksrc/packages root@harbor:~/WorkShop/spksrc/packages# ls npc_armada37xx-6.2_0.26.6-1.spk[scode type="red"]下载地址:https://github.com/balckwilliam/ds119j-nps/releases[/scode]其他架构请参照https://github.com/SynoCommunity/spksrc/wiki/Compile-and-build-rules最后放一张截图
本文主要内容是搭建harbor,并且记录自己的一些踩坑记录，为以后自己方便查阅。一、harbor1.1 harbor介绍[collapse title="harbor介绍" status="true"]Harbor是VMware公司开源的企业级Docker Registry项目，其目标是帮助用户迅速搭建一个企业级的Docker私有镜像仓库。Harbor基于官方Registry V2实现，提供了管理UI，基于角色的访问控制，LDAP集成、镜像复制、以及审计日志等企业用户需求的功能。balabala...具体详情请见baidu[/collapse]二、harbor安装[scode type="blue"]harbor安装没什么太大难度，具体请看代码。[/scode]2.1 首先需要安装docker[scode type="blue"]我选择的docker版本是19.03.8，系统是ubuntu16.04[/scode]参照官方安装教程安装root@vps:~# apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common #安装依赖 root@vps:~# curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - root@vps:~# apt-key fingerprint 0EBFCD88 pub rsa4096 2017-02-22 [SCEA] 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88 uid [ unknown] Docker Release (CE deb) <docker@docker.com> sub rsa4096 2017-02-22 [S] root@vps:~# add-apt-repository \ "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) \ stable" root@vps:~# apt-get update root@vps:~# apt-get install docker-ce docker-ce-cli containerd.io #安装docker，不出意外应该可以成功安装[scode type="blue"]如果是其他系统，请参考官网文档[/scode]2.2 安装docker-composeroot@vps:~# wget https://github.com/docker/compose/releases/download/1.26.0-rc3/docker-compose-Linux-x86_64 #下载docker-compose root@vps:~# cp ./docker-compose-Linux-x86_64 /usr/local/bin/docker-compose #放入/usr/local/bin/文件夹 root@vps:~# chmod +x /usr/local/bin/docker-compose #给执行权限 root@vps:~# docker-compose --version docker-compose version 1.26.0-rc3, build 46118bc5 #查看版本2.3 接下来安装harbor[scode type="blue"]我个人使用的是在线安装harbor[/scode]root@vps:~# wget https://github.com/goharbor/harbor/releases/download/v1.10.1/harbor-online-installer-v1.10.1.tgz #下载harbor root@vps:~# tar -zxvf harbor-online-installer-v1.10.1.tgz #解压 root@vps:~# cd harbor/ #进入harbor目录 root@vps:~# vim harbor.yml #编辑harbor.yml配置文件，每个参数后都有注释，这里就不解释了 root@vps:~# ./install.sh #安装2.4 harbor安装完成了可以去登录进去看看了，默认有一个library公有仓库，可以删除，放个截图：[scode type="blue"]随心所欲修改吧。[/scode]2.5 问题如果你有问题，请跟我接着看：[scode type="blue"]caddy反代问题[/scode]那么接下来问题来了，我使用的是caddy反向代理的，但是现在不是login登录不成功就是push不成功，显示认证失败，反正是各种错误。[scode type="blue"]解决方法：[/scode]如果想要caddy反代，开启https，并且外网使用的话，那么你就得大费周章了，我是这么做的：首先再caddy下配置一下你镜像仓库的域名，并且添加自签证书，像这样[root@server ~]# cat /usr/local/caddy/Caddyfile https://你的域名 { gzip tls 你的邮箱 proxy / https://你的域名:端口号 { websocket transparent } } 并且把caddy的自签证书保存到本地，一会要用。我的caddy自签证书在这个文件夹里[root@server sites]# pwd /root/.caddy/acme/acme-v02.api.letsencrypt.org/sites配置好之后，先不要访问，这时我们需要改hosts[root@server ~]# cat /etc/hosts ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 127.0.0.1 你的域名改好hosts之后,你需要再次修改harbor.yml的配置文件，把hostname: 你的域名,并且把刚刚储存的自签证书上传到一个地方，更改公钥和key文件路径，就像一下这样# Configuration file of Harbor # The IP address or hostname to access admin UI and registry service. # DO NOT use localhost or 127.0.0.1, because Harbor needs to be accessed by external clients. hostname: 你的域名 #填写你的域名 # http related config http: # port for http, default is 80. If https enabled, this port will redirect to https port port: 80 # https related config https: # https port for harbor, default is 443 port: 443 # The path of cert and key files for nginx certificate: /root/crt/xxx.crt private_key: /root/crt/xxx.key #填写域名对应的证书文件和key文件 ... 以下省略END这样部署好，访问你的域名，就可以成功登录，上传镜像了,如下所示：root@vps:~# docker pull xxx/test/nps:0.26.5 0.26.5: Pulling from test/nps 89b6e6d4b47e: Pull complete f65b3d41449d: Pull complete Digest: sha256:d987274633ad3458f8d8437c15cd87b44f5b70145037729523b37b5943cf6e82 Status: Downloaded newer image for xxx/test/nps:0.26.5 三、备份一下命令docker tag 镜像名[:版本号] 你的仓库地址/仓库名称/镜像名称[:版本号] # 为镜像文件打tag docker push 你的仓库地址/仓库名称/镜像名称[:版本号] #上传镜像四、截图至此，完成！！！
Proxmox VE(PVE)开启IOMMO并开启网卡(82576)SRIOV功能【时隔半年，我回来了】
82576在KVM虚拟机下使用网卡的SRIOV功能直通进虚拟机，减少使用Proxmox VE虚拟网卡的NAT功能，提高网卡性能，降低CPU占用。哔哩哔哩链接：文字不带劲，来视频一、pve介绍简单来说：Proxmox VE是一个集成OPENVZ 支持KVM应用的环境。二、单根I/O虚拟化(SRIOV)介绍[collapse title="单根I/O虚拟化(SRIOV)介绍" status="false"]I/O虚拟化可以提高服务器性能和简化硬件要求，而且同时可以在服务器上增加I/O密集型虚拟机的最大数量。SR-IOV技术现已可以开始把具有SR-IOV功能的设备定义成为一种外围设备物理功能模块（PF）并且使之能与主机hypervisor系统直接相互交互信息。PF主要用于在服务器中告诉hypervisor系统关于物理PCI设备运行的状态是否可用。 SR-IOV在操作系统层，现在能在所有的外围物理设备PF下，创建不只一个的虚拟功能设备（VFs）。VFs能共享外围设备的物理资源（像网卡端口或网卡缓存空间）并且与SR-IOV服务器上的虚拟机系统进行关联。SR-IOV能允许一个物理PCIe设备把自身虚拟为多个虚拟PCIe设备。[/collapse]三、基础环境以及软件安装Proxmox VE 5.4CPU:E5645*2网卡：intel 825763.1 软件安装安装基本的软件root@pve:~# apt update root@pve:~# apt-get install net-tools vim ethtool -y\3.2 打开IOMMU在/etc/default/grub文件里，GRUB_CMDLINE_LINUX_DEFAULT行添加以下内容那么使用vim打开文件，添加如果你是intel CPU。GRUB_CMDLINE_LINUX_DEFAULT=" intel_iommu=on pcie_acs_override=downstream"如果你是AMD CPU，那么添加一下内容：GRUB_CMDLINE_LINUX_DEFAULT=" amd_iommu=on pcie_acs_override=downstream"更新grubroot@pve:~# update-grub在/etc/modules文件里添加如下内容：使用vim打开/etc/modules，添加一下内容： vfio vfio_iommu_type1 vfio_pci vfio_virqfd更新并重启root@pve:~# update-initramfs -u -k all root@pve:~# reboot3.3 检查IOMMO功能是否开启root@pve:~# dmesg | grep -e DMAR -e IOMMU -e AMD-Vi [ 1.140539] DMAR: Host address width 40 [ 1.140626] DMAR: DRHD base: 0x000000fbffe000 flags: 0x1 [ 1.140740] DMAR: dmar0: reg_base_addr fbffe000 ver 1:0 cap c90780106f0462 ecap f020f6 [ 1.140865] DMAR: RMRR base: 0x000000000ed000 end: 0x000000000effff [ 1.140959] DMAR: RMRR base: 0x000000bf7ed000 end: 0x000000bf7fffff [ 1.141053] DMAR: ATSR flags: 0x0 [ 1.141445] DMAR: dmar0: Using Queued invalidation [ 1.141552] DMAR: Setting RMRR: [ 1.141911] DMAR: Setting identity map for device 0000:00:1a.0 [0xbf7ed000 - 0xbf7fffff] [ 1.142336] DMAR: Setting identity map for device 0000:00:1a.7 [0xbf7ed000 - 0xbf7fffff] [ 1.142711] DMAR: Setting identity map for device 0000:00:1d.0 [0xbf7ed000 - 0xbf7fffff] [ 1.143088] DMAR: Setting identity map for device 0000:00:1d.1 [0xbf7ed000 - 0xbf7fffff] [ 1.144741] DMAR: Setting identity map for device 0000:00:1d.2 [0xbf7ed000 - 0xbf7fffff] [ 1.145156] DMAR: Setting identity map for device 0000:00:1d.7 [0xbf7ed000 - 0xbf7fffff] [ 1.145301] DMAR: Setting identity map for device 0000:00:1a.0 [0xed000 - 0xeffff] [ 1.145438] DMAR: Setting identity map for device 0000:00:1a.7 [0xed000 - 0xeffff] [ 1.145574] DMAR: Setting identity map for device 0000:00:1d.0 [0xed000 - 0xeffff] [ 1.145710] DMAR: Setting identity map for device 0000:00:1d.1 [0xed000 - 0xeffff] [ 1.145846] DMAR: Setting identity map for device 0000:00:1d.2 [0xed000 - 0xeffff] [ 1.145982] DMAR: Setting identity map for device 0000:00:1d.7 [0xed000 - 0xeffff] [ 1.146120] DMAR: Prepare 0-16MiB unity mapping for LPC [ 1.146460] DMAR: Setting identity map for device 0000:00:1f.0 [0x0 - 0xffffff] [ 1.146781] DMAR: Intel(R) Virtualization Technology for Directed I/O 如果出现一下内容，就代表IOMMO功能开启成功。如果没有出现，那么在/etc/modprobe.d/的任意一个.conf下增加这些内容： options vfio_iommu_type1 allow_unsafe_interrupts=13.3 部署SRIOV首先确定你的intel网卡支持SR-IOV，如果支持，那么继续root@pve:~# echo "options igb max_vfs=6,6,6,6,6,6" > /etc/modprobe.d/igb.conf root@pve:~# depmod -a root@pve:~# update-initramfs -u root@pve:~# reboot解释一下，max_vfs=6,6,6,6,6,6：1.1 这条语句说明最大的虚拟网卡是6个，也就是虚拟6个1.2 6,6···说明我这里有6个intel 82576网卡，每个网卡虚拟出6个，总共是36个虚拟网卡3.4 检查虚拟网卡root@pve:~# dmesg | grep 82576 [ 2.527369] igbvf 0000:07:10.1: Intel(R) 82576 Virtual Function [ 2.532109] igbvf 0000:07:10.3: Intel(R) 82576 Virtual Function [ 2.535583] igbvf 0000:07:10.5: Intel(R) 82576 Virtual Function [ 2.539074] igbvf 0000:07:10.7: Intel(R) 82576 Virtual Function [ 2.542565] igbvf 0000:07:11.1: Intel(R) 82576 Virtual Function [ 2.546055] igbvf 0000:07:11.3: Intel(R) 82576 Virtual Function [ 2.768637] igbvf 0000:07:10.0: Intel(R) 82576 Virtual Function [ 2.771872] igbvf 0000:07:10.2: Intel(R) 82576 Virtual Function [ 2.775080] igbvf 0000:07:10.4: Intel(R) 82576 Virtual Function [ 2.778273] igbvf 0000:07:10.6: Intel(R) 82576 Virtual Function [ 2.781481] igbvf 0000:07:11.0: Intel(R) 82576 Virtual Function [ 2.784682] igbvf 0000:07:11.2: Intel(R) 82576 Virtual Function [ 2.920650] igbvf 0000:05:10.0: Intel(R) 82576 Virtual Function [ 3.128489] igbvf 0000:05:10.2: Intel(R) 82576 Virtual Function [ 3.412422] igbvf 0000:05:10.4: Intel(R) 82576 Virtual Function [ 3.540328] igbvf 0000:05:10.6: Intel(R) 82576 Virtual Function [ 3.580426] igbvf 0000:05:11.0: Intel(R) 82576 Virtual Function [ 3.608433] igbvf 0000:05:11.2: Intel(R) 82576 Virtual Function [ 3.940652] igbvf 0000:05:10.1: Intel(R) 82576 Virtual Function [ 3.960418] igbvf 0000:05:10.3: Intel(R) 82576 Virtual Function [ 3.976422] igbvf 0000:05:10.5: Intel(R) 82576 Virtual Function [ 3.992427] igbvf 0000:05:10.7: Intel(R) 82576 Virtual Function [ 4.008435] igbvf 0000:05:11.1: Intel(R) 82576 Virtual Function [ 4.024426] igbvf 0000:05:11.3: Intel(R) 82576 Virtual Function [ 4.359456] igbvf 0000:04:10.0: Intel(R) 82576 Virtual Function [ 4.380383] igbvf 0000:04:10.2: Intel(R) 82576 Virtual Function [ 4.400395] igbvf 0000:04:10.4: Intel(R) 82576 Virtual Function [ 4.424404] igbvf 0000:04:10.6: Intel(R) 82576 Virtual Function [ 4.440398] igbvf 0000:04:11.0: Intel(R) 82576 Virtual Function [ 4.464396] igbvf 0000:04:11.2: Intel(R) 82576 Virtual Function [ 4.795365] igbvf 0000:04:10.1: Intel(R) 82576 Virtual Function [ 4.820409] igbvf 0000:04:10.3: Intel(R) 82576 Virtual Function [ 4.836453] igbvf 0000:04:10.5: Intel(R) 82576 Virtual Function [ 4.856446] igbvf 0000:04:10.7: Intel(R) 82576 Virtual Function [ 4.872448] igbvf 0000:04:11.1: Intel(R) 82576 Virtual Function [ 4.888444] igbvf 0000:04:11.3: Intel(R) 82576 Virtual Function出现VF代表成功了，那么在你的Proxmox VE 控制面板上，网络一栏就会出现很多网卡[scode type="blue"]注意把原来网卡标记一下，否则会乱的[/scode]以下是我的网卡界面截图四、【问题1】网卡直通windows不识别怎么办windows下网卡提前必须是up状态【重点】就像这样：首先在intel官方下载intel驱动【找到自己的型号】intel网卡驱动下载传送门输入如下指令：pnputil -a PRO1000\Winx64\NDIS62\v1q62x64.inf之后进行正常安装即可参考网址:https://peterkieser.com/2014/07/22/intel-e1g42et-82576-controller-sr-iov-with-windows-2008-r2-guest/五、【问题2】解决群晖不支持驱动问题下载boot文件【支持最新的6.2.2】boot文件下载地址:链接:https://pan.baidu.com/s/1vfeznXGAwvfedskn73vL5Q 提取码:cqjt 复制这段内容后打开百度网盘手机App，操作更方便哦参考网址：https://xpenology.com
因为需要4.19的内核，需要制作树莓派的img镜像，因此，就顺便编译一下树莓派3B+的内核，并制作成树莓派镜像。树莓派镜像制作一、树莓派介绍[collapse title="树莓派介绍" status="false"]树莓派由注册于英国的慈善组织“Raspberry Pi 基金会”开发，Eben·Upton/埃·厄普顿为项目带头人。2012年3月，英国剑桥大学埃本·阿普顿（Eben Epton）正式发售世界上最小的台式机，又称卡片式电脑，外形只有信用卡大小，却具有电脑的所有基本功能，这就是Raspberry Pi电脑板，中文译名"树莓派"。[/collapse]二、基础环境使用X86交叉编译需要10G的硬盘空间[scode type="blue"]本文使用的是ubuntu 16.04的系统[/scode]三、基础环境安装3.1 编译内核用的工具gcc[scode type="blue"]本文使用gcc-4.9下载地址：https://releases.linaro.org/components/toolchain/binaries/[/scode]3.1.1下载并配置gcc64位下载root@ubuntu16:~# wget https://releases.linaro.org/components/toolchain/binaries/4.9-2017.01/aarch64-linux-gnu/gcc-linaro-4.9.4-2017.01-x86_64_aarch64-linux-gnu.tar.xz # 下载64位gcc root@ubuntu16:~# mkdir ~/toolchains # 创建文件夹 root@ubuntu16:~# tar xf gcc-linaro-4.9.4-2017.01-x86_64_aarch64-linux-gnu.tar.xz -C ~/toolchains/ # 解压缩 root@ubuntu16:~# cd ~/toolchains/gcc-linaro-4.9.4-2017.01-x86_64_aarch64-linux-gnu/ root@ubuntu16:~# echo 'export PATH=${PATH}:$(pwd)/bin' > env.sh # 创建环境变量 root@ubuntu16:~# source env.sh # 让环境变量在当前终端生效32位下载root@ubuntu16:~# wget https://releases.linaro.org/components/toolchain/binaries/4.9-2017.01/aarch64-linux-gnu/gcc-linaro-4.9.4-2017.01-i686_aarch64-linux-gnu.tar.xz # 下载32位gcc root@ubuntu16:~# mkdir ~/toolchains # 创建文件夹 root@ubuntu16:~# tar xf gcc-linaro-4.9-2017.01-i686_aarch64-linux-gnu.tar.xz -C ~/toolchains/ # 解压缩 root@ubuntu16:~# cd ~/toolchains/gcc-linaro-4.9.4-2017.01-i686_aarch64-linux-gnu/ root@ubuntu16:~# echo 'export PATH=${PATH}:$(pwd)/bin' > env.sh # 配置环境变量 root@ubuntu16:~# source env.sh # 让环境变量在当前终端生效3.2 安装依赖环境[scode type="blue"]依赖环境安装[/scode]root@ubuntu16:~# sudo apt install build-essential bison make debootstrap qemu-user-static kpartx util-linux vim git libncurses5-dev bc git dosfstools -y # 安装依赖 root@ubuntu16:~# sudo service binfmt-support start # 启动binfmt服务3.3 下载内核并配置3.3.1 下载内核root@ubuntu16:~# mkdir ~/kernel root@ubuntu16:~# cd ~/kernel # 创建文件夹并进入 root@ubuntu16:~# git clone https://github.com/raspberrypi/linux.git # 下载linux内核3.4 下载树莓派的启动文件root@ubuntu16:~# git clone --depth=1 https://github.com/raspberrypi/firmware/ # git上下载boot文件3.5 配置树莓派固件wifi固件树莓派3b1.1 固件1：brcmfmac43430-sdio.binroot@ubuntu16:~# mkdir ~/wifi root@ubuntu16:~# cd ~/wifi # 新建文件夹并进入 root@ubuntu16:~# wget https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/tree/brcm/brcmfmac43430-sdio.bin # 下载brcmfmac43430-sdio.bin1.2 固件2：brcmfmac43430-sdio.txtroot@ubuntu16:~# wget https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/tree/brcm/brcmfmac43430-sdio.raspberrypi,3-model-b.txt # 下载tree/brcm/brcmfmac43430-sdio.raspberrypi,3-model-b.txt root@ubuntu16:~# cp brcmfmac43430-sdio.raspberrypi,3-model-b.txt brcmfmac43430-sdio.txt # 复制并改名树莓派3b+2.1 固件1：brcmfmac43455-sdio.binroot@ubuntu16:~# mkdir ~/wifi root@ubuntu16:~# cd ~/wifi # 创建文件夹并进入 root@ubuntu16:~# https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/tree/brcm/brcmfmac43455-sdio.bin # 下载brcmfmac43455-sdio.bin2.2 固件2：brcmfmac43455-sdio.txtroot@ubuntu16:~# https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/tree/brcm/brcmfmac43455-sdio.raspberrypi,3-model-b-plus.txt # 下载brcmfmac43455-sdio.raspberrypi,3-model-b-plus.txt root@ubuntu16:~# cp brcmfmac43455-sdio.raspberrypi,3-model-b-plus.txt brcmfmac43455-sdio.txt # 复制并改名蓝牙固件树莓派3b1.1 固件：BCM43430A1.hcdroot@ubuntu16:~# mkdir ~/bluetooth root@ubuntu16:~# cd ~/bluetooth root@ubuntu16:~# wget https://github.com/RPi-Distro/bluez-firmware/raw/master/broadcom/BCM43430A1.hcd树莓派3b+2.1 固件：BCM4345C0.hcdroot@ubuntu16:~# mkdir ~/bluetooth root@ubuntu16:~# cd ~/bluetooth root@ubuntu16:~# wget https://github.com/RPi-Distro/bluez-firmware/raw/master/broadcom/BCM4345C0.hcd四、编译内核4.1 检查环境变量root@ubuntu16:~# which aarch64-linux-gnu-gcc4.2 创建内核编译环境变量并检查root@ubuntu16:~# echo 'export ARCH=arm64' >> env.sh root@ubuntu16:~# echo 'export CROSS_COMPILE=aarch64-linux-gnu-' >> env.sh # 创建环境变量 root@ubuntu16:~# source env.sh # 初始化环境变量 root@ubuntu16:~# echo "${ARCH}" # 检查ARCH root@ubuntu16:~# echo "${CROSS_COMPILE}" # 检查CROSS_COMPILE # 如果ARCH为arm64，CROSS_COMPILE为aarch64-linux-gnu-，环境配置正确4.3 编译内核4.3.1 内核编译1root@ubuntu16:~# cd ~/kernel/linux root@ubuntu16:~# make bcmrpi3_defconfig # 生成默认配置文件 root@ubuntu16:~# make menuconfig # 修改默认配置文件4.3.2 内核配置默认为配置如下图所示：如果需要虚拟化支持，请选择[*] Virtualization --- [*] Kernel-based Virtual Machine (KVM) support <M> Host kernel accelerator for virtio net [*] Cross-endian support for vhost # 在Virtualization下的所有选项选中 # 然后按住左右按键找到save保存一下如果需要cgroup支持，请选择General setup ---> -*- Control Group support ---> [*] Memory controller [*] Swap controller [*] Swap controller enabled by default (NEW) [*] IO controller -*- CPU controller ---> [*] CPU bandwidth provisioning for FAIR_GROUP_SCHED [*] Group scheduling for SCHED_RR/FIFO [*] PIDs controller [*] RDMA controller [*] Freezer controller [*] Cpuset controller [*] Include legacy /proc/<pid>/cpuset file [*] Device controller [*] Simple CPU accounting controller 如果需要Checkpoint/restore支持，请选择：[scode type="blue"]使用CRIU必须开启[/scode]General setup ---> [*] Checkpoint/restore support 在内核里选择你需要的驱动例如usb网卡驱动Device Drivers ---> [*] Network device support ---> [*] Wireless LAN ---> [*] Realtek devices <M> Realtek 8187 and 8187B USB support <M> Realtek rtlwifi family of devices ---> <M> Realtek 8192C USB WiFi <M> RTL8723AU/RTL8188[CR]U/RTL819[12]CU (mac80211) support [scode type="blue"]选择完成后选择save后按exit钮退出即可[/scode]4.3.3 内核编译root@ubuntu16:~# make -j 4 # 编译内核五、制作rootfs首先创建rootfs文件夹root@ubuntu16:~# mkdir ~/rootfs/[scode type="blue"]请从以下地址选取rootfs[/scode][collapse title="基本rootfs镜像" status="false"]Archlinux 64 位官方rootfs:http://mirrors.ustc.edu.cn/archlinuxarm/os/ArchLinuxARM-aarch64-latest.tar.gzGentoo 64 位官方rootfs:http://distfiles.gentoo.org/experimental/arm64/Ubuntu 64 位官方rootfs:xenial:http://mirrors.ustc.edu.cn/ubuntu-cdimage/ubuntu-base/releases/xenial/release/ubuntu-base-16.04.5-base-arm64.tar.gzbionic:http://mirrors.ustc.edu.cn/ubuntu-cdimage/ubuntu-base/releases/bionic/release/ubuntu-base-18.04.1-base-arm64.tar.gz[/collapse]我选取的位ubuntu16.04版本root@ubuntu16:~# mkdir -p ~/rootfs/4.19/ # 创建文件夹 root@ubuntu16:~# cd rootfs/4.19 # 进入 root@ubuntu16:~# cp /usr/bin/qemu-aarch64-static usr/bin # 拷贝qemu-aarch64-static到usr/bin挂载文件并进入root@ubuntu16:~# sudo mount -o bind /dev/ dev root@ubuntu16:~# sudo mount -o bind /dev/pts dev/pts root@ubuntu16:~# sudo mount -o bind /proc proc root@ubuntu16:~# sudo mount -o bind /sys sys root@ubuntu16:~# $ sudo cp etc/hosts etc/hosts.bak # 备份原HOSTS root@ubuntu16:~# sudo cp etc/resolv.conf etc/resolv.conf.bak #备份原resolv.conf root@ubuntu16:~# sudo cp /etc/hosts etc/hosts # 复制系统文件 root@ubuntu16:~# sudo cp /etc/resolv.conf etc/resolv.conf # 复制系统文件 root@ubuntu16:~# sudo chroot ./ /bin/sh # 使用chroot进入安装依赖chroot # # 进入后 chroot # passwd root # 更改密码，注意登入需要 chroot # apt update # 更新 chroot # apt install vim wpasupplicant net-tools openssh-server bash-com* netbase iproute2 iputils-ping git # 安装依赖 chroot # exit # 退出卸载文件系统并恢复网络配置root@ubuntu16:~# sudo umount dev/pts root@ubuntu16:~# sudo umount dev root@ubuntu16:~# sudo umount proc root@ubuntu16:~# sudo umount sys # 卸载文件系统 root@ubuntu16:~# sudo mv etc/hosts.bak etc/hosts root@ubuntu16:~# sudo mv etc/resolv.conf.bak etc/resolv.conf # 恢复网络配置计算一下rootfs大小root@ubuntu16:~# sudo du -sh ./ # 有用镜像大小计算公式镜像大小= rootfs大小 + 300M + 200M五、制作镜像文件5.1 分区[scode type="blue"]首先创建images文件[/scode]创建images文件root@ubuntu16:~# mkdir ~/images/ root@ubuntu16:~# cd ~/images/ root@ubuntu16:~# dd bs=1M count=545 if=/dev/zero of=ubuntu.img # 根据镜像大小计算公式计算出的镜像大小来创建，本文创建的大小位545M[scode type="blue"]为镜像分区[/scode]为镜像分区root@ubuntu16:~# cfdisk ubuntu.img[scode type="blue"]分区表选择dos[/scode]分区表选择dos ┌ Select label type ───┐ │ gpt │ │ dos * │ │ sgi │ │ sun │ └──────────────────────┘ Device does not contain a recognized partition table. Select a type to create a new label or press 'L' to load script file. [scode type="blue"]选 new 创建分区,分区大小为100M，并且选择主分区，分区如下所示[/scode] Disk: ubuntu.img Size: 545 MiB, 571473920 bytes, 1116160 sectors Label: dos, identifier: 0xd5f9f036 Device Boot Start End Sectors Size Id Type >> ubuntu.img1 * 2048 206847 204800 100M 83 Linux Free space 206848 1116159 909312 444M ┌──────────────────────────────────────────────────────────────────────────────────────────────────┐ │Partition type: Linux (83) │ │ Attributes: 80 │ └──────────────────────────────────────────────────────────────────────────────────────────────────┘ [ * Bootable] [ Delete ] [ Resize ] [ Quit ] [ Type ] [ Help ] [ Write ] [ Dump ][scode type="blue"]选bootable使刚才创建的分区设定为可启动,Boot下，有一个星号代表设置完成[/scode] Device Boot Start End Sectors Size Id Type >> ubuntu.img1 * 2048 206847 204800 100M 83 Linux Free space 206848 1116159 909312 444M [scode type="blue"]选“type”改变分区标识,找到“W95 FAT32” 并回车，成功之后“Id Type”显示“b W95 FAT32”字样[/scode] Device Boot Start End Sectors Size Id Type >> ubuntu.img1 * 2048 206847 204800 100M 83 Linux b W95 FAT32 Free space 206848 1116159 909312 444M [scode type="blue"]按方向健下，切换到空余空间.选择new新健一个分区，分区使用所有空余空间，选择primary 主分区，成功之后如下显示[/scode] Device Boot Start End Sectors Size Id Type >> ubuntu.img1 * 2048 206847 204800 100M 83 Linux b W95 FAT32 ubuntu.img2 206848 1116159 909312 444M [scode type="blue"]选择Write 将更改写入镜像[/scode]5.2 写入内容到img文件5.2.1用kpartx挂载镜像到looproot@ubuntu16:~/images# kpartx -av ubuntu.img add map loop0p1 (252:2): 0 204800 linear 7:0 2048 add map loop0p2 (252:3): 0 909312 linear 7:0 206848 # 输出的信息就是需要挂载的文件 # loop0p1 为第一个分区 # loop0p2 为第二个分区5.2.2 格式化分区格式化为ext4root@ubuntu16:~/images# sudo mkfs.vfat /dev/mapper/loop0p1 # 格式化第一个分区 root@ubuntu16:~/images# sudo mkfs.ext4 /dev/mapper/loop0p2 # 格式化第二个分区格式化为f2fs【如果你想把第二个分区格式化为f2fs】root@ubuntu16:~/images# sudo apt install f2fs-tools root@ubuntu16:~/images# sudo mkfs.f2fs -f /dev/mapper/loop0p2 # 格式化第二个分区5.2.3挂载镜像root@ubuntu16:~/images# sudo mkdir /mnt/loop0p1 # 创建文件夹 root@ubuntu16:~/images# sudo mount /dev/mapper/loop0p1 /mnt/loop0p1 # 挂载loop0p1 root@ubuntu16:~/images# sudo mkdir /mnt/loop0p2 # 创建文件夹 root@ubuntu16:~/images# sudo mount /dev/mapper/loop0p2 /mnt/loop0p2 # 挂载loop0p25.2.4向镜像里写入内容[scode type="blue"]向第一个分区写入内容[/scode]向第一个分区写入内容[scode type="blue"]本节内容是向第一个分区写入启动引导。[/scode]为第一个分区写入内容root@ubuntu16:~/images# cp -r /root/firmware/boot/* /mnt/loop0p1/ # 复制boot文件到loop0p1 root@ubuntu16:~/images# cd ~/kernel/linux/ # 进入编译的内核的工作目录 root@ubuntu16:~/kernel/linux# sudo cp ./arch/arm64/boot/Image /mnt/loop0p1/kernel8.img # 复制编译好的内核 root@ubuntu16:~/kernel/linux# sudo mv /mnt/loop0p1/bcm2710-rpi-3-b.dtb /mnt/loop0p1/bcm2710-rpi-3-b.dtb_32 root@ubuntu16:~/kernel/linux# sudo mv /mnt/loop0p1/bcm2710-rpi-3-b-plus.dtb /mnt/loop0p1/bcm2710-rpi-3-b-plus.dtb_32 # 将32位的dtb文件更名 root@ubuntu16:~/kernel/linux# sudo cp ./arch/arm64/boot/dts/broadcom/bcm2710-rpi-3-b.dtb /mnt/loop0p1/bcm2710-rpi-3-b.dtb root@ubuntu16:~/kernel/linux# sudo cp ./arch/arm64/boot/dts/broadcom/bcm2710-rpi-3-b-plus.dtb /mnt/loop0p1/bcm2710-rpi-3-b-plus.dtb # 复制64位的dtb文件写cmdline.txtroot@ubuntu16:~/kernel/linux# sudo vim /mnt/loop0p1/cmdline.txt写入内容root=/dev/sda2 rootfstype=ext4 rw rootwait fsck.repair=yes program_usb_boot_mode=1[scode type="blue"]注意：“program_usb_boot_mode=1”为u盘启动，如果内存卡启动请删除“program_usb_boot_mode=1”这行代码[/scode]其他说明1.1 root=/dev/sda2 将第二分区设置为根分区1.2 rootfstype=ext4 根分区类型 f2fs应更换为f2fs1.3 rw 可写挂载跟分区1.4 rootwait 等待内核识别根分区设备后再挂载1.5 fsck.repair=yes 启动时自动检查修复文件系统错误[scode type="blue"]向第二个分区写入内容[/scode]向第二个分区写入内容[scode type="blue"]本节主要内容是安装内核模块、固件和rootfs系统到镜像的第二个分区。[/scode]1.安装内核模块root@ubuntu16:~/kernel/linux# cd ~/kernel/linux #进入编译内核的工作目录 root@ubuntu16:~/kernel/linux# make modules_install INSTALL_MOD_PATH=/mnt/loop0p22.放入wifi和蓝牙固件root@ubuntu16:~/kernel/linux# mkdir -p /mnt/loop0p2/lib/firmware/brcm root@ubuntu16:~/kernel/linux# cp -r ~/wifi/* /mnt/loop0p2/lib/firmware/brcm/ root@ubuntu16:~/kernel/linux# cp -r ~/bluetooth/* /mnt/loop0p2/lib/firmware/brcm/ root@ubuntu16:~/kernel/linux# sync # 同步写入3.写入rootfs系统root@ubuntu16:~# sudo apt install rsync # 安装rsync同步工具 root@ubuntu16:~# sudo rsync -HPavz -q ./ /mnt/loop0p2 # 使用rsync同步到loop0p2分区 root@ubuntu16:~# sync # 同步一下4.卸载分区root@ubuntu16:~/kernel/linux# sudo umount /dev/mapper/loop0p1 root@ubuntu16:~/kernel/linux# sudo umount /dev/mapper/loop0p2 root@ubuntu16:~/kernel/linux# sudo kpartx -dv /dev/loop0 root@ubuntu16:~/kernel/linux# sudo losetup -d /dev/loop0六、测试[scode type="blue"]请自己进行测试，如果按照我的步骤来，应该不会出错，本人已经实验完成。[/scode]
本文主要讲解使用quagga、Docker和quagga搭建简单的BGP网络。使用OVS+Docker+quagga搭建BUG网络首先对本次使用的技术进行一个简单的介绍，接着说明一下本次试验的环境，最后进行BGP简单网络的搭建。1. 简单介绍1.1 BGP网络介绍[collapse title="BGP网络介绍" status="false"]BGP(边界网关协议)主要用于互联网AS(自治系统)之间的互联，BGP的最主要功能在于控制路由的传播和选择最好的路由。中国联通 、中国电信、中国移动、教育网和一些大的民营IDC运营商都具有AS号，全国各大网络运营商多数都是通过BGP协议与自身的AS号来实现多线互联的。使用BGP协议互联后，网络运营商的所有骨干路由设备将会判断到IDC机房IP段的最佳路由，以保证不同网络运营商用户的高速访问。[/collapse]1.2 Docker介绍[collapse title="Docker介绍" status="false"]Docker 是一个开源的应用容器引擎，让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中，然后发布到任何流行的 Linux或Windows 机器上，也可以实现虚拟化。容器是完全使用沙箱机制，相互之间不会有任何接口。[/collapse]1.3 quagga介绍[collapse title="quagga介绍" status="false"]quagga软件原名是Zebra是由一个日本开发团队编写的一个以GNU版权方式发布的软件。它将linux机器打造成一台功能完备的路由器。Quagga支持的路由协议 Quagga能够同时支持RIPv1、RIPv2、RIPng、OSPFv2、OSPFv3、BGP-4和 BGP-4+等诸多TCP/IP协议。其中： RIPv1、RIPv2、OSPFv2适用于Ipv4的自治域系统内部网络路由协议。 BGP-4是用于Ipv4的自治域系统之间的外部网络路由协议。 RIPng、OSPFv3、BGP-4+主要扩展对Ipv6的支持。Quagga的特性 模块化设计：Quagga基于模块化方案的设计，即对每一个路由协议使用单独的守护进程。 运行速度快：因为使用了模块化的设计，使得Quagga的运行速度比一般的路由选择程序要快。 可靠性高：在所有软件模块都失败的情况下，路由器可以继续保持连接并且daemons也会继续运行。故障诊断不必离线的状态下被诊断和更正 支持Ipv6：Quagga不仅支持Ipv4，还支持Ipv6。Quagga的运行机制 由于Quagga采用模块化的设计，因此Quagga运行时要运行多个守护进程，包括ripd ripngd ospfd ospf6d bgpd 和Zebra。 其中，Zebra守护进程用来更新内核的路由表，而其他的守护进程负责进行相应路由选择协议的路由更新。Quagga的好处[/collapse]1.4 OpenVSwitch介绍[collapse title="OpenVSwitch介绍" status="false"]OpenvSwitch，简称OVS是一个虚拟交换软件，主要用于虚拟机VM环境，作为一个虚拟交换机，支持Xen/XenServer, KVM, and VirtualBox多种虚拟化技术。虽然是虚拟交换机，但是其工作原理与物理交换机类似。在虚拟交换机的实现中，其两端分别连接着物理网卡和多块虚拟网卡，同时虚拟交换机内部会维护一张映射表，根据MAC地址寻找对应的虚拟机链路进而完成数据转发。 OpenvSwitch是实现虚拟化网络的重要基础组件，在OpenStack中利用OpenvSwitch作为底层部件来完成虚拟网络提供和租户网络管理。OpenvSwitch可以实现访问控制功能，通过转发规则，可以实现简单的安全行为，包括通过、禁止等。[/collapse]2. 本次运行的环境2.1 系统环境Centos 7.6.18102.2 软件环境Docker 17.06【docker镜像为centos7】OpenVSwitch 2.5.8版本3. BGP网络搭建[scode type="blue"]3.1为首先准备BGP的一些基础环境，[/scode]3.1 BGP环境准备准备Docker和OVS3.1.1 安装Docker和OVS[root@localhost ~]#yum install docker-ce.x86_64 openvswitch.x86_64 -y #安装docker和OVS [root@localhost ~]#systemctl start docker [root@localhost ~]#systemctl start openvswitch #启动docker和OVS3.1.2 Docker下载centos镜像[root@localhost ~]#docker pull centos:latest #下载centos镜像 [root@localhost ~]#docker run -itd --privileged=true --name temp centos:latest /bin/bash #运行centos镜像 [root@localhost ~]#docker exec -i temp yum update -y #更新docker镜像系统 [root@localhost ~]#docker exec -i temp yum install quagga net-tools vim screen -y #在docker镜像里安装quagga等基础环境 [root@localhost ~]#docker commit temp quagga #保存为quagga镜像3.1.3 部署OVS[scode type="blue"]增加OVS网桥[/scode][root@localhost ~]#ovs-vsctl add-br br1 #增加OVS网桥 [root@localhost ~]#ovs-vsctl show 15f3e9bd-93d4-44d5-aba9-752bea391fce Bridge "br1" Port "br1" Interface "br1" type: internal ovs_version: "2.5.8" #查看是否添加成功3.1.4 部署BGP网络[scode type="blue"]网络拓扑图如下所示：[/scode]运行Docker[root@localhost ~]# docker run -itd --privileged=true --network none --name BGP1 quagga:latest /bin/bash #运行docker A [root@localhost ~]# ovs-docker add-port br1 eth1 BGP1 --ipaddress=192.168.2.1/24 [root@localhost ~]# ovs-docker add-port br1 eth2 BGP1 --ipaddress=100.100.0.1/30 #添加容器A网络 [root@localhost ~]# docker run -itd --privileged=true --network none --name BGP2 quagga:latest /bin/bash #运行docker B [root@localhost ~]# ovs-docker add-port br1 eth1 BGP2 --ipaddress=10.10.2.1/24 [root@localhost ~]# ovs-docker add-port br1 eth2 BGP2 --ipaddress=100.100.0.2/30 #添加容器B网络容器BGP1-运行quagga程序这里使用screen放在后台运行[root@localhost ~]# docker attach BGP1 [root@a6a0fd30b609 ~]# echo 'hostname 55dea2659df3'>/etc/quagga/zebra.conf #写入zebra配置文件 [root@a6a0fd30b609 ~]# nohup zebra & #放后台 [root@a6a0fd30b609 ~]# echo '! -*- bgp -*- ! ! BGPd sample configuratin file ! ! $Id: bgpd.conf.sample,v 1.1 2002/12/13 20:15:29 paul Exp $ ! hostname bgpd password zebra !enable password please-set-at-here ! !bgp mulitple-instance ! router bgp 7675 ! bgp router-id 10.0.0.1 ! network 10.0.0.0/8 ! neighbor 10.0.0.2 remote-as 7675 ! neighbor 10.0.0.2 route-map set-nexthop out ! neighbor 10.0.0.2 ebgp-multihop ! neighbor 10.0.0.2 next-hop-self ! ! access-list all permit any ! !route-map set-nexthop permit 10 ! match ip address all ! set ip next-hop 10.0.0.1 ! !log file bgpd.log ! log stdout'> /etc/quagga/bgpd.conf # 写入BGP配置文件 [root@a6a0fd30b609 ~]# nohup bgpd & # 放入后台 [root@a6a0fd30b609 ~]# echo '! -*- ospf -*- ! ! OSPFd sample configuration file ! ! hostname ospfd password zebra !enable password please-set-at-here ! !router ospf ! network 192.168.1.0/24 area 0 ! log stdout'>/etc/quagga/ospfd.conf #写入ospf配置文件 [root@a6a0fd30b609 ~]# nohup ospfd & [root@a6a0fd30b609 ~]# netstat -tunlp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:2601 0.0.0.0:* LISTEN 61/zebra tcp 0 0 0.0.0.0:2604 0.0.0.0:* LISTEN 101/ospfd tcp 0 0 0.0.0.0:2605 0.0.0.0:* LISTEN 95/bgpd tcp 0 0 0.0.0.0:179 0.0.0.0:* LISTEN 95/bgpd tcp6 0 0 :::2601 :::* LISTEN 61/zebra tcp6 0 0 :::2604 :::* LISTEN 101/ospfd tcp6 0 0 :::2605 :::* LISTEN 95/bgpd tcp6 0 0 :::179 :::* LISTEN 95/bgpd #检测端口容器BGP2-运行quagga程序[scode type="blue"]配置内容同上[/scode]配置BGP网络[scode type="yellow"]对容器BGP1进行配置[/scode][scode type="blue"]我们要确认当前没有已经配置的BGP会话。在一些版本，我们可能会发现一个AS号为7675的BGP会话。由于我们不需要这个会话，所以把它移除。[/scode][root@a6a0fd30b609 ~]# vtysh #进入quagga路由器 bgpd# configure terminal bgpd(config)# no router bgp 7675 bgpd(config)# router bgp 100 bgpd(config-router)# no auto-summary bgpd(config-router)# no synchronization bgpd(config-router)# neighbor 100.100.0.2 remote-as 200 bgpd(config-router)# neighbor 100.100.0.2 description "provider B" bgpd(config-router)# exit bgpd(config)# exit bgpd# write # 对BGP进行设置[scode type="yellow"]对容器BGP2进行配置[/scode][root@ea07e44ee83b ~]# vtysh Router-B# configure terminal Router-B(config)#no router bgp 7675 Router-B(config)# router bgp 200 Router-B(config)#no auto-summary Router-B(config)#no synchronizaiton Router-B(config-router)# neighbor 100.100.0.1 remote-as 100 Router-B(config-router)# neighbor 100.100.0.1 description "provider A" Router-B(config-router)#exit Router-B(config)#exit Router-B# write[scode type="yellow"]检测此步骤是否搭建成功,如果显示如下，说明此步骤没问题。[/scode]ea07e44ee83b# show ip bgp summary BGP router identifier 100.100.0.2, local AS number 200 RIB entries 0, using 0 bytes of memory Peers 1, using 4560 bytes of memory Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd 100.100.0.1 4 100 3 4 0 0 0 00:01:12 0 Total number of neighbors 1 配置BGP前缀通告AS 100将以192.168.2.1/24作为通告，在我们的例子中AS 200将同样以10.10.2.1/24作为通告。这些前缀需要被添加到BGP配置如下。#在路由器-A中： bgpd# configure terminal bgpd(config)# router bgp 100 bgpd(config-router)# network 192.168.2.1/24 bgpd(config-router)# exit bgpd(config)# exit bgpd# write #在路由器-B中： ea07e44ee83b# configure terminal ea07e44ee83b(config)# router bgp 200 ea07e44ee83b(config-router)# network 10.10.2.1/24 ea07e44ee83b(config-router)# exit ea07e44ee83b(config)# exit ea07e44ee83b# write #两个路由器会根据需要开始通告前缀。测试前缀通告[scode type="blue"]首先，确认前缀的数量是否被改变了,输入“show ip bgp summary”查看：[/scode]ea07e44ee83b# show ip bgp summary BGP router identifier 100.100.0.2, local AS number 200 RIB entries 3, using 336 bytes of memory Peers 1, using 4560 bytes of memory Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd 100.100.0.1 4 100 11 12 0 0 0 00:08:15 1 Total number of neighbors 1[scode type="blue"]查看所接收的更多前缀细节，我们可以使用以下命令，“show ip bgp neighbors 邻居IP advertised-routes”这个命令用于显示邻居所接收到的前缀总数。[/scode]ea07e44ee83b# show ip bgp neighbors 100.100.0.1 advertised-routes BGP table version is 0, local router ID is 100.100.0.2 Status codes: s suppressed, d damped, h history, * valid, > best, i - internal, r RIB-failure, S Stale, R Removed Origin codes: i - IGP, e - EGP, ? - incomplete Network Next Hop Metric LocPrf Weight Path *> 10.10.2.0/24 100.100.0.2 0 32768 i Total number of prefixes 1 [scode type="blue"]查看哪一个前缀是我们从邻居接收到的,可以使用如下命令：“show ip bgp neighbors 邻居IP routes”[/scode]ea07e44ee83b# show ip bgp neighbors 100.100.0.1 routes BGP table version is 0, local router ID is 100.100.0.2 Status codes: s suppressed, d damped, h history, * valid, > best, i - internal, r RIB-failure, S Stale, R Removed Origin codes: i - IGP, e - EGP, ? - incomplete Network Next Hop Metric LocPrf Weight Path *> 192.168.2.0 100.100.0.1 0 0 100 i Total number of prefixes 1 [scode type="blue"]也可以查看所有的BGP路由器：“show ip bgp”[/scode]ea07e44ee83b# show ip bgp BGP table version is 0, local router ID is 100.100.0.2 Status codes: s suppressed, d damped, h history, * valid, > best, i - internal, r RIB-failure, S Stale, R Removed Origin codes: i - IGP, e - EGP, ? - incomplete Network Next Hop Metric LocPrf Weight Path *> 10.10.2.0/24 0.0.0.0 0 32768 i *> 192.168.2.0 100.100.0.1 0 0 100 i Total number of prefixes 23.1.5 测试BGP网络[scode type="blue"]在BGP1中ping BGP2中的192.168.2.1和10.10.2.1都可以ping通[/scode]测试方法1ea07e44ee83b# ping 192.168.2.1 PING 192.168.2.1 (192.168.2.1) 56(84) bytes of data. 64 bytes from 192.168.2.1: icmp_seq=1 ttl=64 time=0.947 ms 64 bytes from 192.168.2.1: icmp_seq=2 ttl=64 time=0.095 ms 64 bytes from 192.168.2.1: icmp_seq=3 ttl=64 time=0.101 ms 64 bytes from 192.168.2.1: icmp_seq=4 ttl=64 time=0.120 ms ^C --- 192.168.2.1 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3001ms rtt min/avg/max/mdev = 0.095/0.315/0.947/0.365 ms ea07e44ee83b# ping 10.10.2.1 PING 10.10.2.1 (10.10.2.1) 56(84) bytes of data. 64 bytes from 10.10.2.1: icmp_seq=1 ttl=64 time=0.240 ms 64 bytes from 10.10.2.1: icmp_seq=2 ttl=64 time=0.072 ms 64 bytes from 10.10.2.1: icmp_seq=3 ttl=64 time=0.080 ms 64 bytes from 10.10.2.1: icmp_seq=4 ttl=64 time=0.092 ms ^C --- 10.10.2.1 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 2999ms rtt min/avg/max/mdev = 0.072/0.121/0.240/0.069 ms #ping测试测试方法2[root@localhost ~]# docker run -itd --privileged=true --network none --name test quagga:latest /bin/bash [root@localhost ~]# ovs-docker add-port br1 eth1 test --ipaddress=192.168.2.100/24 [root@localhost ~]# docker exec -i test ip route add default via 192.168.2.1 [root@localhost ~]# docker exec -i test ping 10.10.2.1 -c 4 PING 10.10.2.1 (10.10.2.1) 56(84) bytes of data. 64 bytes from 10.10.2.1: icmp_seq=1 ttl=63 time=1.07 ms 64 bytes from 10.10.2.1: icmp_seq=2 ttl=63 time=0.228 ms 64 bytes from 10.10.2.1: icmp_seq=3 ttl=63 time=0.235 ms 64 bytes from 10.10.2.1: icmp_seq=4 ttl=63 time=0.117 ms --- 10.10.2.1 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3001ms rtt min/avg/max/mdev = 0.117/0.414/1.078/0.386 ms # 如果可以通，说明配置成功