rustdesk自建服务器

1. 安装pm2

sudo apt update && sudo apt upgrade;
sudo apt install npm;
sudo npm install -g pm2;

2.安装rustdesk server

sudo apt install wget
wget --no-check-certificate https://github.com/rustdesk/rustdesk-server/releases/download/1.1.6/rustdesk-server-linux-x64.zip
unzip rustdesk-server-linux-x64.zip

3. 启动

pm2 start hbbs
pm2 start hbbr
pm2 startup
pm2 save

开放防火墙 TCP(21115, 21116, 21117, 21118, 21119)
UDP(21116)

ID服务器: curl ip.sb
Key: cat id_*.pub

PM2常用命令:

  1. pm2 start <script_file|config_file> [options] 启动指定应用,如pm2 start index.js –name httpServer;
  2. pm2 stop <appName> [options] 停止指定应用,如pm2 stop httpServer;
  3. pm2 list  把所有pm2启动实例列举出来,注意:pm2 stop 某个项目后,该项目还会存在pm2 list 的列表里面, 只是状态是 stop, 要想去掉该项目,用pm2 delete
  4. pm2 reload|restart <appName> [options]  重启指定应用,如pm2 restart httpServer;
  5. pm2 show <appName> [options] 显示指定应用详情,如pm2 show httpServer;
  6. pm2 delete <appName> [options] 删除指定应用,如pm2 delete httpServer,如果修改应用配置行为,最好先删除应用后,重新启动方才生效,如修改脚本入口文件;
  7. pm2 kill 杀掉pm2管理的所有进程;
  8. pm2 logs <appName>  查看指定应用的日志,即标准输出和标准错误;
  9. pm2 monit 监控各个应用进程cpu和memory使用情况;
  10. pm2 startOrReload <appName> 如果项目没有启动就执行 start  如果项目正在运行 就执行relaod

方法二

2.防火墙设置

系统重装好了,我们需要在服务器的防火墙中开放RustDesk需要的端口。放行以下端口

TCP:21115-21119
UDP:21116
温馨提示:
有些服务器Linux系统预装了防火墙,你需要给以上端口放行,或者关闭防火墙!

安装 RustDesk服务器

1.使用FinalShell服务器管理软件

2.更新系统源和软件

apt update      //更新源
apt upgrade     //更新软件 

运行一键安装Rustdesk脚本

1.系统重启好后,粘贴RustDesk Server一键安装脚本,回车开始安装。

一键安装脚本:

wget https://raw.githubusercontent.com/techahold/rustdeskinstall/master/install.sh
chmod +x install.sh
./install.sh

一键更新脚本:

wget https://raw.githubusercontent.com/smianao/rustdeskinstall/master/update.sh && chmod +x update.sh && ./update.sh

查看并复制密钥Key备用

客户端配置

1.主控端电脑,安装rustdesk客户端

2. 手动配置

主界面依次点击设置-网络-解锁网络设置,ID/中继服务器设置如下:

ID服务器:为你云服务器IP地址
中继服务器:为你云服务器IP地址
API服务器:空
Key:上一步获取的key

3. 通过导入导出配置

ID/中继服务器界面,可导入导出配置

4.将配置写入rustdesk.exe 文件名中

将Windows客户端名称修改为如下格式,发给被控电脑使用即可。

rustdesk-host=<你的服务器IP/域名>,key=<你的key>.exe

利用GitHub Actions编译客户端(更加隐私安全)

如果担心中继服务器信息泄露,或者有更严苛的分发需求,可以使用GitHub Actions,将中继服务器以及key等信息,直接编译到客户端里。被控端直接运行你编译的客户端,无需再填入中继服务器等信息,就可以正常实现被控。但是使用GitHub Actions编译的时间会比较长一些,一般是1小时多些。也是本人比较推荐的方式,可以做到比较安全的连接。

1.准备工作

编译客户端的前提,你需要一个Github账号,没有的可以注册一个,非常简单,这里就不演示了!
https://github.com/

2.创建分支

访问Github的RustDesk项目
登录Github账号
点击 “Fork”创建分支项目,简单说,就是把该项目克隆到你的github仓库
参数保持默认,点击这里创建,等待创建完成。
到这里就创建完成了

3.设置环境变量

将服务器等信息,填入变量,以便接下来的编译。
回到刚刚创建的分支项目,转到 “Settings → Secrets and variables → Actions”
单击“New repository secret”,变量名:RENDEZVOUS_SERVER,对应值填写服务器IP/域名
点击 “Add secret”
单击“New repository secret”,变量名: RS_PUB_KEY,对应值填写key
点击 “Add secret”
单击“New repository secret”,变量名: API_SERVER,对应值填写API地址
点击 “Add secret”

4.启用工作流权限

在您刚刚创建的 fork上,转到“Settings → Actions → General”
右侧,上方勾选“Allow all actions and reusable workflows”
点击”Save”
滑动到底部,在 Workflow permissions 下启用 “Read and write permissions”
点击“Save”

5.启动工作流

点击上方“Actions”(项目横向主菜单)
在左侧,选择 “Flutter Nightly Build” 然后在右侧,单击 “Enable workflow”
最后,您可以单击 “Run workflow” 为所有支持的平台构建 RustDesk 客户端

6.客户端下载

Github编译的时间可能会久一点,过一个小时左右,你可以在你创建的分支项目下,看是否有编译好的客户端,如果刚好有编译好的,你便可以下载对应平台的客户端使用。

7.客户端使用演示

以Windows平台为例,双击运行或安装编译好的客户端,进入网络查看,没有对应的服务器信息,因为我们直接将该信息编译到程序里,操作使用下,可以正常远控。这样,我们便可直接将客户端,发给被控端使用,而无需再手动编辑服务器等信息,可谓非常便捷!

Oracle Cloud甲骨文云初始配置

用Putty登陆入,用户名是opc或ubuntu

切换到root角色

sudo -i
  1. 安装相关依赖

CentOS如下

yum -y install wget
yum update -y && yum install curl -y

Ubuntu如下

apt-get install wget
apt-get update -y && apt-get install curl -y
  1. 删除、关闭、打开各自系统的无用附件、防火墙、端口及规则

CentOS系统

删除多余附件

systemctl stop oracle-cloud-agent
systemctl disable oracle-cloud-agent
systemctl stop oracle-cloud-agent-updater
systemctl disable oracle-cloud-agent-updater

停止firewall

systemctl stop firewalld.service

禁止firewall开机启动

systemctl disable firewalld.service


Ubuntu系统

开放所有端口

iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
iptables -F

Ubuntu镜像默认设置了Iptable规则,关闭它

apt-get purge netfilter-persistent
reboot

或者强制删除

rm -rf /etc/iptables &amp;&amp; reboot

ssh

方法一:

使用下例中ssky-keygen和ssh-copy-id,仅需通过3个步骤的简单设置而无需输入密码就能登录远程Linux主机。 
ssh-keygen 创建公钥和密钥。 
ssh-copy-id 把本地主机的公钥复制到远程主机的authorized_keys文件上。
ssh-copy-id 也会给远程主机的用户主目录(home)和~/.ssh, 和~/.ssh/authorized_keys设置合适的权限 。

步骤1: 用 ssh-key-gen 在本地主机上创建公钥和密钥
ligh@local-host$ ssh-keygen -t  rsa
Enter file in which to save the key (/home/jsmith/.ssh/id_rsa):[秘钥文件名] 
Enter passphrase (empty for no passphrase): [秘钥密码(直接输入回车即为不带密码的秘钥)]
Enter same passphrase again: [重复输入秘钥密码]
Your identification has been saved in /home/jsmith/.ssh/id_rsa.
Your public key has been saved in /home/jsmith/.ssh/id_rsa.pub. 
The key fingerprint is: 33:b3:fe:af:95:95:18:11:31:d5:de:96:2f:f2:35:f9 
ligh@local-host

步骤2: 用 ssh-copy-id 把公钥复制到远程主机上
ligh@local-host$ ssh-copy-id -i ~/.ssh/id_rsa.pub  root@192.168.0.3
ligh@remote-host‘s password:
Now try logging into the machine, with ―ssh ?remote-host‘‖, and check in: 
.ssh/authorized_keys to make sure we haven‘t added extra keys that you weren‘t expecting.
[注: ssh-copy-id 把密钥追加到远程主机的 .ssh/authorized_key 上.]

步骤3: 直接登录远程主机
ligh@local-host$ ssh remote-host 
Last login: Sun Nov 16 17:22:33 2008 from 192.168.1.2 
[注: SSH 不会询问密码.] 
ligh@remote-host$ 
[注: 你现在已经登录到了远程主机上]

方法二

一、概述

1、就是为了让两个linux机器之间使用ssh不需要用户名和密码。采用了数字签名RSA或者DSA来完成这个操作

2、模型分析

假设 A 为客户机器,B 为目标机;

要达到的目的:
A机器ssh登录B机器无需输入密码;
加密方式选 rsa|dsa均可以,默认dsa

二、具体操作流程

单向登陆的操作过程(能满足上边的目的):
1、登录A机器 
2、ssh-keygen -t [rsa|dsa],将会生成密钥文件和私钥文件 id_rsa,id_rsa.pub或id_dsa,id_dsa.pub
3、将 .pub 文件复制到B机器的 .ssh 目录, 并 cat id_rsa.pub >> ~/.ssh/authorized_keys
4、大功告成,从A机器登录B机器的目标账户,不再需要密码了;(直接运行 #ssh 用户名@ip )

http://blog.csdn.net/kongqz/article/details/6338690

以下两点注意:

1、配置私钥
a、使用命令ssh-keygen -t rsa生成密钥,会生成一个私钥和一个公钥,在提示输入passphrase时如果不输入,直接回车,那么以后你登录服务器就不会验证密码,否则会要求你输入passphrase,默认会将私钥放在/(用户名)/.ssh/id_rsa公钥放在
/用户名/.ssh/id_rsa.pub。
b、将公钥拷贝到远程服务器上的/(用户名)/.ssh/authorized_keys文件
(scp /用户名/.ssh/id_rsa.pub server:/用户名/.ssh/authorized_keys),注意,文件名一定要叫authorized_keys。权限600
c、客户端上保留私钥,公钥留不留都可以。也就是服务器上要有公钥,客户端上要有私钥。这样就可以实现无密码验证登录了。
2、如果想要获得最大化的安全性,禁止口令登录,可以修改远程主机上/etc/ssh/sshd_conf中的
PasswordAuthentication yes 改为
PasswordAuthentication no
也即只能使用密匙认证的openssh,禁止使用口令认证

1.禁用 root 用户通过 ssh 登录: 编辑 /etc/ssh/sshd_config,设置 PermitRootLogin 为 no 可禁止普通用户以 root 用户身份远程登录。
2.禁止对 SSH 进行基于密码的身份验证:编辑 /etc/ssh/sshd_config,设置 PasswordAuthentication 为 no 可禁止对 SSH 进行基于密码的身份验证。
注:若要禁止基于密码的身份验证,但允许对 root 执行基于私钥的身份验证,可设置 PermitRootLogin 为 prohibit-password 。

1、/etc/ssh/ssh_config配置文件

选项参数                                      说明
Host *                      选项“Host”只对能够匹配后面字串的计算机有效。“*”表示所有的计算机。
ForwardAgent no             设置连接是否经过验证代理(如果存在)转发给远程计算机。
ForwardX11 no                设置X11连接是否被自动重定向到安全的通道和显示集(DISPLAY set)
RhostsAuthentication no        设置是否使用基于rhosts的安全验证
RhostsRSAAuthentication no       设置是否使用用RSA算法的基于rhosts的安全验证
RSAAuthentication yes              设置是否使用RSA算法进行安全验证
PasswordAuthentication yes        设置是否使用口令验证
FallBackToRsh no                      设置如果用ssh连接出现错误是否自动使用rsh
UseRsh no                           设置是否在这台计算机上使用“rlogin/rsh”
BatchMode no            如果设为“yes”,passphrase/password(交互式输入口令)的提示将被禁止。当不能交互式输入口令的时候,这个选项对脚本文件和批处理任务十分有用
CheckHostIP yes         设置ssh是否查看连接到服务器的主机的IP地址以防止DNS欺骗。建议设置为“yes”
StrictHostKeyChecking no   如果设置成“yes”,ssh就不会自动把计算机的密匙加入“$HOME/.ssh/known_hosts”文件,并且一旦计算机的密匙发生了变化,就拒绝连接
IdentityFile ~/.ssh/identity        设置从哪个文件读取用户的RSA安全验证标识
Port 22                                   设置连接到远程主机的端口
Cipher blowfish                           设置加密用的密码
EscapeChar ~                              设置escape字符

2、/etc/ssh/sshd_config配置文件

Port 22            SSH 预设使用 22 这个 port,您也可以使用多的 port !
Protocol 2,1    选择的 SSH 协议版本,可以是 1 也可以是 2 ,如果要同时支持两者,就必须要使用 2,1 
ListenAddress 0.0.0.0       监听的主机适配卡!举个例子来说,如果您有两个 IP,分别是 192.168.0.100 及 192.168.2.20 ,那么只想要开放 192.168.0.100 时,就可以写如同下面的样式:
ListenAddress 192.168.0.100     只监听来自 192.168.0.100 这个 IP 的SSH联机。如果不使用设定的话,则预设所有接口均接受 SSH
PidFile /var/run/sshd.pid        可以放置 SSHD 这个 PID 的档案!左列为默认值
LoginGraceTime 600                当使用者连上 SSH server 之后,会出现输入密码的画面,在该画面中,在多久时间内没有成功连上 SSH server ,就断线!时间为秒!
Compression yes                                是否可以使用压缩指令?
HostKey /etc/ssh/ssh_host_key                  SSH version 1 使用的私钥
HostKey /etc/ssh/ssh_host_rsa_key              SSH version 2 使用的 RSA 私钥
HostKey /etc/ssh/ssh_host_dsa_key              SSH version 2 使用的 DSA 私钥
KeyRegenerationInterval 3600                    由前面联机的说明可以知道, version 1 会使用 server 的 Public Key ,每隔一段时间来重新建立一次!时间为秒!
ServerKeyBits 768                               Server key 的长度!
SyslogFacility AUTH                             当有人使用 SSH 登入系统的时候,SSH会记录信息
LogLevel INFO                                   登录记录的等级—》全部
PermitRootLogin no                               是否允许 root 登入!预设是允许的,但是建议设定成 no!
UserLogin no                                    在 SSH 底下本来就不接受 login 这个程序的登入!
StrictModes yes                          当使用者的 host key 改变之后,Server 就不接受联机
RSAAuthentication yes                    是否使用纯的 RSA 认证!?仅针对 version 1 !
PubkeyAuthentication yes                  是否允许 Public Key ?只有 version 2
AuthorizedKeysFile   .ssh/authorized_keys   设定若要使用不需要密码登入的账号时,那么那个账号的存放档案所在名
RhostsAuthentication no                       本机系统不使用 .rhosts , .rhosts 不安全!
IgnoreRhosts yes                              是否取消使用 ~/.ssh/.rhosts 来做为认证!
RhostsRSAAuthentication no    针对version 1使用 rhosts 档案在/etc/hosts.equiv配合 RSA 演算方式来进行认证!
HostbasedAuthentication no     这个项目与上面的项目类似,不过是给 version 2 使用的!
IgnoreUserKnownHosts no         是否忽略家目录内的 ~/.ssh/known_hosts 这个档案所记录的主机内容
PasswordAuthentication yes      密码验证当然是需要的!
PermitEmptyPasswords no         上面那一项如果设定为 yes 的话,这一项就最好设定为 no ,这个项目在是否允许以空的密码登入!
ChallengeResponseAuthentication yes   挑战任何的密码认证!所以,任何 login.conf 规定的认证方式,均可适用!
PAMAuthenticationViaKbdInt yes    是否启用其它的 PAM 模块!启用这个模块将会导致 PasswordAuthentication 设定失效!
 
与Kerberos 有关的参数设定!底下不用设定
KerberosAuthentication no
KerberosOrLocalPasswd yes
KerberosTicketCleanup yes
KerberosTgtPassing no
 
有关在 X-Window 底下使用的相关设定
X11Forwarding yes
X11DisplayOffset 10
X11UseLocalhost yes
 
PrintMotd no   登入后是否显示出一些信息呢?例如上次登入的时间、地点等,预设是 yes 为了安全,可以考虑改为 no 
PrintLastLog yes   显示上次登入的信息!预设也是 yes
KeepAlive yes       一般而言,如果设定这项目的话,那么 SSH Server 会传送KeepAlive 的讯息给 Client 端,以确保两者的联机正常!在这个情况下,任何一端死掉后, SSH 可以立刻知道!而不会有僵尸程序的发生!
UsePrivilegeSeparation yes    使用者的权限设定项目!
MaxStartups 10                同时允许几个尚未登入的联机画面
DenyUsers *                   设定受抵挡的使用者名称
AllowUsers *                  设定允许的使用者名称

zerotier 内网穿透

安装:curl -s https://install.zerotier.com | sudo bash

一.配置 Linux 的数据转发和路由控制

  • Linux 系统内核可以通过 sysctliptables 两个命令控制网络数据转.
  • 查看内核 IP 转发设置,0 表示处于关闭状态:
  • $ sudo sysctl net.ipv4.ip_forward
  • net.ipv4.ip_forward = 0
  • 编辑配置文件开启 Linxu 内核的 IP 数据转发:
  • sudo vim /etc/sysctl.conf
  • 将第 28 行的注释去掉,设置 net.ipv4.ip_forward=1
  • net.ipv4.ip_forward=1 # lin 28
  • 激活配置文件设置:
  • $ sudo sysctl -p
  • net.ipv4.ip_forward = 1
  • 查看内核 IP 转发设置,1 表示开启状态:
  • $ sudo sysctl net.ipv4.ip_forward
  • net.ipv4.ip_forward = 1

二.查看网口信息

$ ifconfig
可以发现,在 Ubuntu 上 enp123s0f0 用来接入真实物理网络,zt7u3fcxwr 用来接入 zerotier 虚拟网络. 注意后续命令中使用网口名称的地方~
使用 iptables 启用 enp123s0f0 及zt7u3fcxwr  的网络地址转换和 IP 伪装:
sudo iptables -t nat -A POSTROUTING -o enp123s0f0 -j MASQUERADE
sudo iptables -t nat -A POSTROUTING -o zt7u3fcxwr -j MASQUERADE

iptables -I FORWARD -i zthxxxx -j ACCEPT
iptables -I FORWARD -o zthxxxx -j ACCEPT
iptables -t nat -I POSTROUTING -o zthxxxx -j MASQUERADE





允许流量转发和跟踪活动连接:
sudo iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
接下来设置从zt7u3fcxwr 到 enp123s0f0 流量转发。 反向规则不是必需的,因为在本文所述场景下没有用到:
sudo iptables -A FORWARD -i zt7u3fcxwr -o enp123s0f0 -j ACCEPT

linux流量转发

iptables -t nat -A POSTROUTING -o vmbr0(真实网卡) -j MASQUERADE

iptables -A FORWARD -m conntrack –ctstate RELATED,ESTABLISHED -j ACCEPT

 iptables -A FORWARD -i zero网卡 -o vmbr0(真实网卡) -j ACCEPT

安装 apt-get install iptables-persistent

netfilter-persistent save (保持iptables规则)

  1. 加入网络命令‌:
    • 加入网络:zerotier-cli join 网络ID
    • 查看当前连接的网络列表:zerotier-cli listnetworks
  2. 查看状态和服务命令‌:
    • 查看Zerotier服务状态:zerotier-cli info
    • 启动Zerotier服务:sudo systemctl start zerotier-one.service
    • 设置Zerotier服务开机自启动:sudo systemctl enable zerotier-one.service
    • 停止Zerotier服务:sudo systemctl stop zerotier-one.service

流量转发

sudo iptables -t nat -A POSTROUTING -o $PHY_IFACE -j MASQUERADE sudo iptables -A FORWARD -i $PHY_IFACE -o $ZT_IFACE -m state –state RELATED,ESTABLISHED -j ACCEPT sudo iptables -A FORWARD -i $ZT_IFACE -o $PHY_IFACE -j ACCEPT

这三条 iptables 规则用于配置网络地址转换(NAT)和数据包转发;

含义如下:

  1. 规则 1: sudo iptables -t nat -A POSTROUTING -o $PHY_IFACE -j MASQUERADE这条规则在 nat 表的 POSTROUTING 链中添加了一条规则。-o $PHY_IFACE 表示这条规则适用于所有通过 $PHY_IFACE 这个网络接口(通常是物理接口)出去的数据包。-j MASQUERADE 指定了 NAT 操作中的伪装(masquerading)。这意味着,当数据包从 $PHY_IFACE 发送出去时,其源 IP 地址会被替换为 $PHY_IFACE 的 IP 地址。这通常用于允许内部网络通过一个公共 IP 地址进行外部通信;
  2. 规则 2: sudo iptables -A FORWARD -i $PHY_IFACE -o $ZT_IFACE -m state --state RELATED,ESTABLISHED -j ACCEPT这条规则在 filter 表的 FORWARD 链中添加了一条规则。-i $PHY_IFACE 表示适用于从 $PHY_IFACE 这个接口进入的数据包,-o $ZT_IFACE 表示这些数据包要转发到 $ZT_IFACE 这个接口。-m state --state RELATED,ESTABLISHED 指定了只有那些与已有连接相关或已经建立的连接的数据包才被接受(ACCEPT)。这个规则通常用于允许来自外部网络的返回流量进入内部网络,从而支持诸如 HTTP 会话等;
  3. 规则 3: sudo iptables -A FORWARD -i $ZT_IFACE -o $PHY_IFACE -j ACCEPT这条规则在 filter 表的 FORWARD 链中添加了一条规则。-i $ZT_IFACE 表示适用于从 $ZT_IFACE 这个接口进入的数据包,-o $PHY_IFACE 表示这些数据包要转发到 $PHY_IFACE 这个接口。-j ACCEPT 表示这些数据包会被接受并转发。这条规则允许来自 $ZT_IFACE 的流量经过路由器转发到 $PHY_IFACE,从而实现网络之间的数据传输;总结:
  • 第一条规则用于设置源地址伪装,允许内部网络设备通过一个公共 IP 地址进行外部通信;
  • 第二条规则允许返回流量和已经建立的连接的数据包从外部网络进入内部网络;
  • 第三条规则允许来自内部网络的数据包被转发到外部网络;

转发

# 启用 IPv4 转发 echo ‘net.ipv4.ip_forward=1’ >> /etc/sysctl.conf sysctl -p # 配置 NAT 和转发规则 iptables -t nat -A POSTROUTING -o <内网网卡> -j MASQUERADE iptables -A FORWARD -i <ZeroTier虚拟网卡> -o <内网网卡> -m state –state RELATED,ESTABLISHED -j ACCEPT iptables -A FORWARD -i <内网网卡> -o <ZeroTier虚拟网卡> -j ACCEPT # 保存规则(OpenWrt) /etc/init.d/firewall save

甲骨文云服务器Oracle cloud 分配并启用 IPv6 地址教程

过程1: 创建IPv6 CIDR块

(1)打开Oracle 虚拟云网络控制台

(2)选择需要添加IPv6的VCN
添加CIDR

(3)点击左侧菜单栏中的CIDR Blocks/Prefixes

(4)点击右侧界面中的 Add CIDR Block/IPv6 Prefix
添加CIDR

(5)勾选Assign an Oracle allocated IPv6 /56 preflx,并点击添加CIDR按钮

添加CIDR

(6)稍等一会后,你会发现在CIDR Blocks界面中多出了一个 /56 的 IPv6 段了

    将IPv6 CIDR块与子网关联

    1. 打开Oracle 虚拟云网络控制台
    2. 点击页面左侧边栏的 子网
    3. 选择使用中的子网
    4. 在做侧边栏中找到IPv6 Prefixes 进入并在右侧界面中点击Add IPv6 Prefix
    5. 在弹出的界面中勾选Assign an Oracle allocated IPv6 /64 prefix 在下面的输入框中输入2位16进制的代码

    过程2:更新安全列表规则

    要使实例能够通过 IPv6 发送和接收流量,您必须更新安全组规则以包含 IPv6 地址的规则。比如你的网站 80端口

    更新入站安全组规则

    1. 打开Oracle 虚拟云网络控制台
    2. 点击页面左侧边栏的 安全列表 并选择正在使用的列表。
    3. 在入站规则选项卡中,选择编辑入站规则。
    4. 对于允许 IPv4 流量的每条规则,选择添加规则并配置该规则以允许相应的 IPv6 流量。例如,要添加允许通过 IPv6 的所有 HTTP 流量的规则,请为“类型 ”和“源”选择HTTP。::/0
    5. 保存规则。

    过程3:更新路由表

    更新公有子网的路由表

    1. 打开Oracle 虚拟云网络控制台
    2. 点击页面左侧边栏的 路由表。选择正在使用的路由表
    3. 选择路由表。选择添加路由规则
    4. 选择添加路线。选择::/0目的地 。
    5. 保存更改。

    为实例分配IPv6地址

    1. 打开实例控制台
    2. 进入需要改为IPv6的实例详情页面
    3. 找到左侧边栏里的附加的 VNIC,并点击右侧的VNIC
    4. 选择左侧边栏里的IPv6 地址后选择右侧的分配IPv6地址,在弹出的页面中选择自动从 IPv6 前缀中分配
    5. 现在我们回到实例的管理面板,查看主机的详细信息,就会发现已经被分配了新的IPv6地址了。

    Linux win 系统使用 USBIP 远程共享 USB 设备

    操作步骤

    配置 USB Server

    • 在本地计算机上(Ubuntu),依次执行以下命令,安装 USBIP 并加载相关的内核模块。
      1. sudo apt-get install usbip
      2. sudo modprobe usbip-core
      3. sudo modprobe vhci-hcd
      4. sudo modprobe usbip_host
    • 插入 USB 设备,并执行以下命令,查询可用的 USB 设备。
      1. usbip list --local
      例如,在本地计算机上插入一个usb,返回如下结果:
    • busid 1-1 (1bc0:0055)
      unknown vendor : unknown product (1bc0:0055)
    • 记录 busid 的值,并依次执行以下命令,启动监听服务,指定 USBIP 端口号,共享 USB 设备。
      1. sudo usbipd -D [--tcp-port PORT]sudo usbip bind -b [busid]
      例如,USBIP 指定端口号为3240端口(即 USBIP 的默认端口),busid 为1-1,则执行以下命令:
      1. sudo usbipd -D
      2. sudo usbip bind -b 1-1
    • (可选)执行以下命令,创建 SSH 隧道,并使用端口监听。 说明没有公网 IP 的本地计算机,请执行此步骤。如您的本地计算机有公网 IP,请跳过此步骤。
      1. ssh -Nf -R USB/IP指定端口号:localhost:USB/IP指定端口号 root@your_hostyour_host
      表示云服务器的 IP 地址。 例如,USBIP 的端口号为3240端口,云服务器的 IP 地址为192.168.15.24,则执行以下命令:
      1. ssh -Nf -R 3240:localhost:3240 root@192.168.15.24
    • unknown vendor : unknown product (1bc0:0055)

    配置 USB Client

    1. 依次执行以下命令,下载 USB/IP 源。
      1. rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
      2. rpm -ivh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
    2. 依次执行以下命令,安装 USBIP。
      1. yum -y install kmod-usbip usbip-utils
      2. modprobe usbip-core
      3. modprobe vhci-hcd
      4. modprobe usbip-host
    3. 执行以下命令,查询云服务器可用的 USB 设备。
      1. usbip list --remote 127.0.0.1
      例如,找到usb 的信息,返回如下结果:
      1. Exportable USB devices
      2. ======================
      3. -127.0.0.1 1-1.3: unknown vendor : unknown product (1bc0:0055) product(096e:031b):/sys/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.3:(Defined at Interface level)(00/00/00)
    4. 执行以下命令,将 USB 设备绑定至服务器中。
      1. usbip attach --remote=127.0.0.1 --busid=1-1.3
    5. 执行以下命令,查看当前 USB 设备列表。
      1. lsusb
      返回类似如下信息,即表示共享成功。

    配置 WIN Client

    1.下载usbip-win-0.3.6-dev

    https://github.com/cezanne/usbip-win

    1. 执行以下命令,查询云服务器可用的 USB 设备。
      1. usbip list --remote 127.0.0.1
      例如,找到usb 的信息,返回如下结果:
      1. Exportable USB devices
      2. ======================
      3. -127.0.0.1 1-1.3: unknown vendor : unknown product (1bc0:0055) product(096e:031b):/sys/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.3:(Defined at Interface level)(00/00/00)
    2. 执行以下命令,将 USB 设备绑定至
      1. usbip attach --remote=127.0.0.1 --busid=1-1.3

    jq

    1.  jq简介与安装    

        jq是一款命令行下处理JSON数据的工具。

        其可以接受标准输入,命令管道或者文件中的JSON数据,经过一系列的过滤器(filters)和表达式的转后形成我们需要的数据结构并将结果输出到标准输出中。

        jq的这种特性使我们可以很容易地在Shell脚本中调用它。

    1) jq编译安装
    jq 的源代码可以从其代码仓库中获得。编译 jq 的指令如下:
    [root@ss-server ~]# git clone https://github.com/stedolan/jq.git
    [root@ss-server ~]# cd jq
    [root@ss-server ~]# autoreconf -i
    [root@ss-server ~]# ./configure --disable-maintainer-mode
    [root@ss-server ~]# make
    [root@ss-server ~]# make install
     
    2)jq直接安装(centos7可以直接yum安装jq)
    [root@ss-server ~]# yum install -y jq
    [root@ss-server ~]# jq --version
    jq-1.5

    2.  基本用法

    一.  格式化

    1.  将一行数据使用json格式输出

    [root@k8s-master ~]# echo -n '{"id":1, "name":"zhangsan", "score":[75, 85, 90]}'|jq .
    {
      "id": 1,
      "name": "zhangsan",
      "score": [
        75,
        85,
        90
      ]
    }

    (2).  将json格式输出到一行

    [root@k8s-master ~]# jq -c . <<eof
    > {
    >   "id": 1,
    >   "name": "zhangsan",
    >   "score": [
    >     75,
    >     85,
    >     90
    >   ]
    > }
    > eof
    {"id":1,"name":"zhangsan","score":[75,85,90]} 

    二.  属性提取

    1.  取id的值

    [root@k8s-master ~]# echo  '{"id":1, "name":"zhangsan", "score":[75, 85, 90]}' | jq '.id'
    1

    2.  取name的值

    [root@k8s-master ~]# echo  '{"id":1, "name":"zhangsan", "score":[75, 85, 90]}' | jq '.name'
    "zhangsan"

    3.  取name的值,去掉双引号

    [root@k8s-master ~]# echo  '{"id":1, "name":"zhangsan", "score":[75, 85, 90]}' | jq -r '.name'
    zhangsan

     4.  取多层值

    [root@k8s-master ~]# echo -n '{"id":1, "name":"zhangsan", "attr":{"height":1.78,"weight":"60kg"}}'|jq '.attr.height'
    1.78

    5.  取数组值

    $ echo -n '{"id":1, "name":"zhangsan", "score":[75, 85, 90]}'|jq -r '.score[0]'
    75
     
    $ echo -n '[75, 85, 90]'|jq -r '.[0]'
    75
     
    # 数组截取
    $ echo -n '[75, 85, 90]'|jq -r '.[1:3]'
    [
      85,
      90
    ]
     
    # []展开数组
    $ echo -n '[75, 85, 90]'|jq '.[]'
    75
    85
    90

     6.  展开所有结构

    [root@k8s-master ~]# echo  '{"id":1, "name":"zhangsan", "score":[75, 85, 90]}' | jq -c '..'
    {"id":1,"name":"zhangsan","score":[75,85,90]}
    1
    "zhangsan"
    [75,85,90]
    75
    85
    90

    7.  其他情况

    # 从非对象类型中提取字段,会报错
    $ echo -n '{"id":1, "name":"zhangsan", "attr":{"height":1.78,"weight":"60kg"}}'|jq '.name.alias'
    jq: error (at <stdin>:0): Cannot index string with string "alias"
     
    # 使用?号可以避免这种报错
    $ echo -n '{"id":1, "name":"zhangsan", "attr":{"height":1.78,"weight":"60kg"}}'|jq '.name.alias?'
     
    # //符号用于,当前面的表达式取不到值时,执行后面的表达式
    $ echo -n '{"id":1, "name":"zhangsan", "attr":{"height":1.78,"weight":"60kg"}}'|jq '.alias//.name'
    "zhangsan"

    三.  管道,逗号与括号

    1.  管道可以将值从前一个命令传送到后一个命令

    [root@k8s-master ~]# echo -n '{"id":1, "name":"zhangsan", "attr":{"height":1.78,"weight":"60kg"}}'|jq '.attr|.height'
    1.78

    2.  可以做一些简单的运算

    $ echo -n '{"id":1, "name":"zhangsan", "attr":{"height":1.78,"weight":"60kg"}}'|jq '.attr|.height*100|tostring + "cm"'
    "178cm"

    3. 使用逗号可以输出多个结果

    [root@k8s-master ~]# echo -n '{"id":1, "name":"zhangsan", "attr":{"height":1.78,"weight":"60kg"}}'|jq -r '.attr.height,.attr.weight'
    1.78
    60kg

    四.  将读取的元素,都当作字符串,使用-R参数

    [root@k8s-master ~]# seq 4 | jq -R '.'
    "1"
    "2"
    "3"
    "4"

    五.  将json元素,变成json数组元素

    [root@k8s-master ~]# echo -n '{"id":1, "name":"zhangsan"}' | jq -s '.'
    [
      {
        "id": 1,
        "name": "zhangsan"
      }
    ]

    六.  数据构造

    $ cat data.txt
    id  name      age  score
    1   zhangsan  17   75
    2   lisi      16   80
    3   wangwu    18   85
    4   zhaoliu   18   90
     
    # 每行分割成数组,[]构造新的数组输出
    $ tail -n+2 data.txt|jq -R '[splits("\\s+")]' -c
    ["1","zhangsan","17","75"]
    ["2","lisi","16","80"]
    ["3","wangwu","18","85"]
    ["4","zhaoliu","18","90"]
     
    $ jq -n '{id:1, name:"zhangsan"}' -c
    {"id":1,"name":"zhangsan"}
     
    # 每行转换为对象,{}构造新的对象格式输出
    $ tail -n+2 data.txt|jq -R '[splits("\\s+")] | {id:.[0]|tonumber, name:.[1], age:.[2], score:.[3]}' -c
    {"id":1,"name":"zhangsan","age":"17","score":"75"}
    {"id":2,"name":"lisi","age":"16","score":"80"}
    {"id":3,"name":"wangwu","age":"18","score":"85"}
    {"id":4,"name":"zhaoliu","age":"18","score":"90"}
     
    # \()字符串占位变量替换
    $ cat data.json
    {"id":1,"name":"zhangsan","age":"17","score":"75"}
    {"id":2,"name":"lisi","age":"16","score":"80"}
    {"id":3,"name":"wangwu","age":"18","score":"85"}
    {"id":4,"name":"zhaoliu","age":"18","score":"90"}
     
    $ cat data.json |jq '"id:\(.id),name:\(.name),age:\(.age),score:\(.score)"' -r
    id:1,name:zhangsan,age:17,score:75
    id:2,name:lisi,age:16,score:80
    id:3,name:wangwu,age:18,score:85
    id:4,name:zhaoliu,age:18,score:90 

    七.  基础函数

    # has函数,检测对象是否包含key
    $ echo -n '{"id":1,"name":"zhangsan","age":"17","score":"75"}'|jq 'has("id")'
    true
     
    # del函数,删除某个属性
    $ echo -n '{"id":1,"name":"zhangsan","age":"17","score":"75"}'|jq 'del(.id)' -c
    {"name":"zhangsan","age":"17","score":"75"}
     
    # map函数,对数组中每个元素执行表达式计算,计算结果组织成新数组
    $ seq 4|jq -s 'map(. * 2)' -c
    [2,4,6,8]
     
    # 上面map函数写法,其实等价于这个写法
    $ seq 4|jq -s '[.[]|.*2]' -c
    [2,4,6,8]
     
    # keys函数,列出对象属性
    $ echo -n '{"id":1,"name":"zhangsan","age":"17","score":"75"}'|jq 'keys' -c
    ["age","id","name","score"]
     
    # to_entries函数,列出对象键值对
    $ echo -n '{"id":1,"name":"zhangsan","age":"17","score":"75"}'|jq 'to_entries' -c
    [{"key":"id","value":1},{"key":"name","value":"zhangsan"},{"key":"age","value":"17"},{"key":"score","value":"75"}]
     
    # length函数,计算数组或字符串长度
    $ jq -n '[1,2,3,4]|length'
    4
     
    # add函数,计算数组中数值之和
    $ seq 4|jq -s 'add'
    10
     
    # tostring与tonumber,类型转换
    $ seq 4|jq 'tostring|tonumber'
    1
    2
    3
    4
     
    # type函数,获取元素类型
    $ jq 'type' <<eof
    1
    "zhangsan"
    true
    null
    {"id":1}
    [75, 80, 85]
    eof
     
    "number"
    "string"
    "boolean"
    "null"
    "object"
    "array"

    八.  过滤,排序,分组函数

    $ cat data.json
    {"id":1,"name":"zhangsan","sex": 0, "age":"17","score":"75"}
    {"id":2,"name":"lisi","sex": 1, "age":"16","score":"80"}
    {"id":3,"name":"wangwu","sex": 0, "age":"18","score":"85"}
    {"id":4,"name":"zhaoliu","sex": 0, "age":"18","score":"90"}
     
    # select函数用于过滤,类似SQL中的where
    $ cat data.json |jq 'select( (.id>1) and (.age|IN("16","17","18")) and (.name != "lisi") or (has("attr")|not) and (.score|tonumber >= 90) )' -c
    {"id":3,"name":"wangwu","sex":0,"age":"18","score":"85"}
    {"id":4,"name":"zhaoliu","sex":0,"age":"18","score":"90"}
     
    # 有一些简化的过滤函数,如arrays, objects, iterables, booleans, numbers, normals, finites, strings, nulls, values, scalars
    # 它们根据类型过滤,如objects过滤出对象,values过滤出非null值等
    $ jq -c 'objects' <<eof
    1
    "zhangsan"
    true
    null
    {"id":1}
    [75, 80, 85]
    eof
     
    {"id":1}
     
    $ jq -c 'values' <<eof
    1
    "zhangsan"
    true
    null
    {"id":1}
    [75, 80, 85]
    eof
     
    1
    "zhangsan"
    true
    {"id":1}
    [75,80,85]
     
    # 选择出id与name字段,类似SQL中的select id,name
    $ cat data.json|jq -s 'map({id,name})[]' -c
    {"id":1,"name":"zhangsan"}
    {"id":2,"name":"lisi"}
    {"id":3,"name":"wangwu"}
    {"id":4,"name":"zhaoliu"}
     
    # 提取前2行,类似SQL中的limit 2
    $ cat data.json|jq -s 'limit(2; map({id,name})[])' -c
    {"id":1,"name":"zhangsan"}
    {"id":2,"name":"lisi"}
     
    # 按照age、id排序,类似SQL中的order by age,id
    $ cat data.json|jq -s 'sort_by((.age|tonumber), .id)[]' -c
    {"id":2,"name":"lisi","sex":1,"age":"16","score":"80"}
    {"id":1,"name":"zhangsan","sex":0,"age":"17","score":"75"}
    {"id":3,"name":"wangwu","sex":0,"age":"18","score":"85"}
    {"id":4,"name":"zhaoliu","sex":0,"age":"18","score":"90"}
     
     
    # 根据sex与age分组,并每组聚合计算count(*)、avg(score)、max(id)
    $ cat data.json |jq -s 'group_by(.sex, .age)[]' -c
    [{"id":1,"name":"zhangsan","sex":0,"age":"17","score":"75"}]
    [{"id":3,"name":"wangwu","sex":0,"age":"18","score":"85"},{"id":4,"name":"zhaoliu","sex":0,"age":"18","score":"90"}]
    [{"id":2,"name":"lisi","sex":1,"age":"16","score":"80"}]
     
    $ cat data.json |jq -s 'group_by(.sex, .age)[]|{sex:.[0].sex, age:.[0].age, count:length, avg_score:map(.score|tonumber)|(add/length), scores:map(.score)|join(","), max_id:map(.id)|max }' -c                
    {"sex":0,"age":"17","count":1,"avg_score":75,"scores":"75","max_id":1}
    {"sex":0,"age":"18","count":2,"avg_score":87.5,"scores":"85,90","max_id":4}
    {"sex":1,"age":"16","count":1,"avg_score":80,"scores":"80","max_id":2}

    九.  字符串操作函数

    # contains函数,判断是否包含,实际也可用于判断数组是否包含某个元素
    $ echo hello | jq -R 'contains("he")'
    true
     
    # 判断是否以he开头
    $ echo hello | jq -R 'startswith("he")'
    true
     
    # 判断是否以llo结尾
    $ echo hello | jq -R 'endswith("llo")'
    true
     
    # 去掉起始空格
    $ echo ' hello '|jq -R 'ltrimstr(" ")|rtrimstr(" ")'
    "hello"
     
    # 大小写转换
    $ echo hello|jq -R 'ascii_upcase'
    "HELLO"
     
    $ echo HELLO|jq -R 'ascii_downcase'
    "hello"
     
    # 字符串数组,通过逗号拼接成一个字符串
    $ seq 4|jq -s 'map(tostring)|join(",")'
    "1,2,3,4"
     
    # json字符串转换为json对象
    $ echo -n '{"id":1,"name":"zhangsan","age":"17","attr":"{\"weight\":56,\"height\":178}"}'|jq '.attr = (.attr|fromjson)' -c
    {"id":1,"name":"zhangsan","age":"17","attr":{"weight":56,"height":178}}
     
    # json对象转换为json字符串
    $ echo -n '{"id":1,"name":"zhangsan","age":"17","attr":{"weight":56,"height":178}}'|jq '.attr = (.attr|tojson)'
    {
      "id": 1,
      "name": "zhangsan",
      "age": "17",
      "attr": "{\"weight\":56,\"height\":178}"
    }
     
    $ cat data.txt
    id:1,name:zhangsan,age:17,score:75
    id:2,name:lisi,age:16,score:80
    id:3,name:wangwu,age:18,score:85
    id:4,name:zhaoliu,age:18,score:90
     
    # 正则表达式过滤,jq使用的是PCRE
    $ cat data.txt|jq -R 'select(test("id:\\d+,name:\\w+,age:\\d+,score:8\\d+"))' -r
    id:2,name:lisi,age:16,score:80
    id:3,name:wangwu,age:18,score:85
     
    # 正则拆分字符串
    $ cat data.txt|jq -R '[splits(",")]' -cr
    ["id:1","name:zhangsan","age:17","score:75"]
    ["id:2","name:lisi","age:16","score:80"]
    ["id:3","name:wangwu","age:18","score:85"]
    ["id:4","name:zhaoliu","age:18","score:90"]
     
    # 正则替换字符串
    $ cat data.txt |jq -R 'gsub("name"; "nick")' -r
    id:1,nick:zhangsan,age:17,score:75
    id:2,nick:lisi,age:16,score:80
    id:3,nick:wangwu,age:18,score:85
    id:4,nick:zhaoliu,age:18,score:90
     
    # 正则表达式捕获数据
    $ cat data.txt|jq -R 'match("id:(?<id>\\d+),name:(?<name>\\w+),age:\\d+,score:8\\d+")' -cr
    {"offset":0,"length":30,"string":"id:2,name:lisi,age:16,score:80","captures":[{"offset":3,"length":1,"string":"2","name":"id"},{"offset":10,"length":4,"string":"lisi","name":"name"}]}
    {"offset":0,"length":32,"string":"id:3,name:wangwu,age:18,score:85","captures":[{"offset":3,"length":1,"string":"3","name":"id"},{"offset":10,"length":6,"string":"wangwu","name":"name"}]}
     
    # capture命名捕获,生成key是捕获组名称,value是捕获值的对象
    $ cat data.txt|jq -R 'capture("id:(?<id>\\d+),name:(?<name>\\w+),age:\\d+,score:8\\d+")' -rc
    {"id":"2","name":"lisi"}
    {"id":"3","name":"wangwu"}
     
    # 正则扫描输入字符串
    $ cat data.txt|jq -R '[scan("\\w+:\\w+")]' -rc
    ["id:1","name:zhangsan","age:17","score:75"]
    ["id:2","name:lisi","age:16","score:80"]
    ["id:3","name:wangwu","age:18","score:85"]
    ["id:4","name:zhaoliu","age:18","score:90"]

    十.  日期函数

    # 当前时间缀
    $ jq -n 'now'
    1653820640.939947
     
    # 将时间缀转换为0时区的分解时间(broken down time),形式为 年 月 日 时 分 秒 dayOfWeek dayOfYear
    $ jq -n 'now|gmtime' -c
    [2022,4,29,10,45,5.466768980026245,0,148]
     
    # 将时间缀转换为本地时区的分解时间(broken down time)
    $ jq -n 'now|localtime' -c
    [2022,4,29,18,46,5.386353015899658,0,148]
     
    # 分解时间转换为时间串
    $ jq -n 'now|localtime|strftime("%Y-%m-%dT%H:%M:%S")' -c
    "2022-05-29T18:50:33"
     
    # 与上面等效
    $ jq -n 'now|strflocaltime("%Y-%m-%dT%H:%M:%SZ")'
    "2022-05-29T19:00:40Z"
     
    # 时间串解析为分解时间
    $ date +%FT%T|jq -R 'strptime("%Y-%m-%dT%H:%M:%S")' -c
    [2022,4,29,18,51,27,0,148]
     
    # 分解时间转换为时间缀
    $ date +%FT%T|jq -R 'strptime("%Y-%m-%dT%H:%M:%S")|mktime'
    1653850310 

    十一.  高级用法

    $ cat data.json
    {"id":1,"name":"zhangsan","sex": 0, "age":"17","score":"75"}
    {"id":2,"name":"lisi","sex": 1, "age":"16","score":"80"}
    {"id":3,"name":"wangwu","sex": 0, "age":"18","score":"85"}
    {"id":4,"name":"zhaoliu","sex": 0, "age":"18","score":"90"}
     
    # 单变量定义
    $ cat data.json| jq '.id as $id|$id'
    1
    2
    3
    4
     
    # 对象展开式变量定义
    $ cat data.json |jq '. as {id:$id,name:$name}|"id:\($id),name:\($name)"'
    "id:1,name:zhangsan"
    "id:2,name:lisi"
    "id:3,name:wangwu"
    "id:4,name:zhaoliu"
     
    $ cat data.json
    ["1","zhangsan","17","75"]
    ["2","lisi","16","80"]
    ["3","wangwu","18","85"]
    ["4","zhaoliu","18","90"]
     
    # 数组展开式变量定义
    $ cat data.json|jq '. as [$id,$name]|"id:\($id),name:\($name)"'
    "id:1,name:zhangsan"
    "id:2,name:lisi"
    "id:3,name:wangwu"
    "id:4,name:zhaoliu"
     
    # 分支结构
    $ cat data.json|jq '. as [$id,$name]|if ($id>"1") then "id:\($id),name:\($name)" else empty end'
    "id:2,name:lisi"
    "id:3,name:wangwu"
    "id:4,name:zhaoliu"
     
    # 循环结构,第一个表达式条件满足时,执行只每二个表达式
    # 循环结构除了while,还有until、recurse等
    $ echo 1|jq 'while(.<100; .*2)'
    1
    2
    4
    8
    16
    32
    64
     
    # 自定义计算3次方的函数
    $ echo 2|jq 'def cube: .*.*. ; cube'
    8

    CDN 筛选

    #!/bin/bash
    ##版本:V2.1.2
    #新功能,支持ip地址全自动下载,更新优选完毕后推送至TG,再也不怕脚本没有成功运行了。
    #使用脚本需要安装jq和timeout,新增openwrt专用cf_RE.sh文件,运行cf_RE.sh即可在openwrt安装jq和timeout两个扩展。
    #其他linux请自行安装jq和timeout。
    #主程序为ip_down.sh。

    ###################################################################################################
    export LANG=zh_CN.UTF-8
    ###################################################################################################

    ##cloudflare配置
    #cloudflare账号邮箱
    x_email=*********************
    #填写需要DDNS的完整域名
    #支持多域名:域名需要填写在括号中,每个域名之间用“空格”相隔。
    #例如:(cdn.test.com) 或者 (cdn1.test.com cdn2.test.com cdn3.test.com)
    CDNhostname=****************
    #区域ID
    zone_id=********************************
    #Global API Key(获取你的API令牌,你的API密钥就是你的登陆密码)
    api_key=****************************
    $CLIEN=v2raya.service
    ###################################################################################################
    ##CloudflareST配置
    #测速地址
    CFST_URL=https://download.parallels.com/desktop/v15/15.1.5-47309/ParallelsDesktop-15.1.5-47309.dmg
    #测速线程数量;越多测速越快,性能弱的设备 (如路由器) 请勿太高;(默认 200 最多 1000 )
    CFST_N=200
    # 指定测速端口;延迟测速/下载测速时使用的端口;(默认 443 端口)
    CFST_TP=8443
    #下载测速数量;延迟测速并排序后,从最低延迟起下载测速的数量;(默认 10 个)
    CFST_DN=10
    #平均延迟上限;只输出低于指定平均延迟的 IP,可与其他上限/下限搭配;(默认9999 ms 这里推荐配置250 ms)
    CFST_TL=250
    #平均延迟下限;只输出高于指定平均延迟的 IP,可与其他上限/下限搭配、过滤假墙 IP;(默认 0 ms 这里推荐配置40)
    CFST_TLL=40
    #下载速度下限;只输出高于指定下载速度的 IP,凑够指定数量 [-dn] 才会停止测速;(默认 0.00 MB/s 这里推荐5.00MB/s)
    CFST_SL=3
    #更新几个 默认10个
    CFST_P=10
    #####################################################################################################
    # 定义下载链接和保存路径
    download_url=”https://zip.baipiao.eu.org/”
    save_path=”/root/txt.zip”
    extracted_folder=”/root/txt” # 解压后的文件夹路径
    ###################################################################################################

    # 定义最大尝试次数
    max_attempts=10
    current_attempt=1
    ###################################################################################################
    # 关闭开启科学上网
    systemctl stop $CLIEN;
    #sleep 20s
    # 循环尝试下载
    while [ $current_attempt -le $max_attempts ]
    do
    # 下载文件
    wget “${download_url}” -O $save_path

    # 检查是否下载成功
    if [ $? -eq 0 ]; then
    break
    else
    echo “Download attempt $current_attempt failed.”
    current_attempt=$((current_attempt+1))
    fi
    done
    ###################################################################################################

    # 检查是否下载成功
    if [ $current_attempt -gt $max_attempts ]; then
    echo “Failed to download the file after $max_attempts attempts.”
    else
    # 删除原来的txt文件夹内容
    rm -rf $extracted_folder/*

    # 解压文件
    unzip $save_path -d $extracted_folder

    # 删除压缩包
    rm $save_path

    echo “File downloaded and unzipped successfully.”
    ###################################################################################################
    # 合并文件为ip.txt
    # 合并所有含有-1-443.txt的文本文件到一个新文件中
    merged_file=”/root/CloudflareST/merged_ip.txt”
    cat $extracted_folder/*-1-$CFST_TP.txt > $merged_file
    ###################################################################################################
    # 移动到ip.txt到程序总目录

    # 将合并后的文件移动到/root/CloudflareST/ip.txt并覆盖原文件
    mv -f “$merged_file” “/root/cdn/ip.txt”
    echo “Merged text files containing ‘-1-$CFST_TP.txt’ moved and renamed as ‘ip.txt’ in /root/cdn.”
    fi
    ###################################################################################################
    ipv4Regex=”((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])”;
    #默认关闭小云朵
    proxy=”false”;
    #验证cf账号信息是否正确
    res=$(curl -s -X GET “https://api.cloudflare.com/client/v4/zones/${zone_id}” -H “X-Auth-Email:$x_email” -H “X-Auth-Key:$api_key” -H “Content-Type:application/json”);
    resSuccess=$(echo “$res” | jq -r “.success”);
    if [[ $resSuccess != “true” ]]; then
    pushmessage=”登陆错误,检查cloudflare账号信息填写是否正确!”
    # source cf_push;
    exit 1;
    fi
    echo “Cloudflare账号验证成功”;
    #停止科学上网服务

    systemctl stop $CLIEN;
    echo “已停止$CLIEN”;


    #判断是否配置测速地址
    if [[ “$CFST_URL” == http* ]] ; then
    CFST_URL_R=”-url $CFST_URL”;
    else
    CFST_URL_R=””;
    fi

    if [ “$IP_ADDR” = “ipv6” ] ; then
    #开始优选IPv6
    ./CloudflareST $CFST_URL_R -tp $CFST_TP -n $CFST_N -dn $CFST_DN -tl $CFST_TL -tll $CFST_TLL -sl $CFST_SL -p $CFST_P -f ipv6.txt
    else
    #开始优选IPv4
    ./CloudflareST $CFST_URL_R -tp $CFST_TP -n $CFST_N -dn $CFST_DN -tl $CFST_TL -tll $CFST_TLL -sl $CFST_SL -p $CFST_P
    fi
    echo “测速完毕”;
    #systemctl start $CLIEN;
    #echo “已重启$CLIEN”;
    echo “为保证cloudflareAPI连接正常 将在30秒后开始更新域名解析”;
    sleep 3s;
    #开始循环
    echo “正在更新域名,请稍后…”;
    x=0;
    #while [[ ${x} -lt $num ]]; do
    # CDNhostname=${hostname[$x]};
    #获取优选后的ip地址

    # ipAddr=$(sed -n “$((x + 2)),1p” result.csv | awk -F, ‘{print $1}’);
    # echo “开始更新第$((x + 1))个—$ipAddr”;

    while (($x<3))
    do
    ipAddr[$x]=$(sed -n “$((x + 2)),1p” result.csv | awk -F, ‘{print $1}’);
    echo “更新的IP${ipAddr[$x]}”;
    let “x++”;
    done
    #开始DDNS
    #if [[ $ipAddr =~ $ipv4Regex ]]; then
    recordType=”A”;
    # else
    recordType=”AAAA”;
    # fi
    # listDnsApi=”https://api.cloudflare.com/client/v4/zones/${zone_id}/dns_records?type=${recordType}&name=${CDNhostname}”;
    # createDnsApi=”https://api.cloudflare.com/client/v4/zones/${zone_id}/dns_records”;

    # res=$(curl -s -X GET “$listDnsApi” -H “X-Auth-Email:$x_email” -H “X-Auth-Key:$api_key” -H “Content-Type:application/json”);



    # 获取现有记录ID(如果存在)
    res=$(curl -s -X GET “https://api.cloudflare.com/client/v4/zones/${zone_id}//dns_records?type=A&name=$CDNhostname” \
    -H “Authorization: Bearer $api_key” \
    -H “X-Auth-Email:$x_email” \
    -H “X-Auth-Key:$api_key”\
    -H “Content-Type:application/json”)
    #EXISTING_RECORD_ID=$(echo “$res” | jq -r “.result[$id].id”)
    # echo ${EXISTING_RECORD_ID};

    i=0;
    for IP in “${ipAddr[@]}”
    do
    recordId=$(echo “$res” | jq -r “.result[$i].id”);
    recordIp=$(echo “$res” | jq -r “.result[$i].content”);
    echo “$recordId”
    if [[ $recordIp = “$IP” ]]; then
    echo “更新失败,获取最快的IP与云端相同”;
    resSuccess=false;
    elif [[ $recordId = “null” ]]; then
    sleep 3s;
    res_Success =$(curl -s -X POST “https://api.cloudflare.com/client/v4/zones/$zone_id/dns_records” \
    -H “Authorization: Bearer $api_key” \
    -H “X-Auth-Email:$x_email” \
    -H “X-Auth-Key:$api_key”\
    -H “Content-Type: application/json” \
    –data ‘{
    “type”: “A”,
    “name”: “‘$CDNhostname'”,
    “content”: “‘$IP'”,
    “ttl”: 60,
    “proxied”: false
    }’);
    resSuccess=$(echo “res_Success” | jq -r “.success”);
    # echo “Added A record for $CDNhostname with IP: $IP”;
    else
    sleep 3s;
    res_Success=$(curl -s -X PUT “https://api.cloudflare.com/client/v4/zones/$zone_id/dns_records/$recordId” \
    -H “Authorization: Bearer $api_key” \
    -H “X-Auth-Email:$x_email” \
    -H “X-Auth-Key:$api_key”\
    -H “Content-Type: application/json” \
    –data ‘{
    “type”: “A”,
    “name”: “‘$CDNhostname'”,
    “content”: “‘$IP'”,
    “ttl”: 60,
    “proxied”: false
    }’);
    #echo “Updated A record for $CDNhostname with IP: $IP”
    resSuccess=$(echo “$res_Success” | jq -r “.success”);
    # echo “Updated A record for $CDNhostname with IP: $IP”;
    fi

    if [[ $resSuccess = “true” ]]; then
    echo “$CDNhostname更新成功$IP”;
    else
    echo “$CDNhostname更新失败$IP”;
    fi
    let “i++”;

    #会生成一个名为informlog的临时文件作为推送的内容。
    done > informlog
    pushmessage=$(cat informlog);
    systemctl start $CLIEN;
    echo “已停止$CLIEN”;
    #source cf_push;
    exit 0;

    青龙

    
    
    
    

    拉取:docker pull whyour/qinglong

    指定拉取:docker pull whyour/qinglong:******

    运行:docker run -dit -v $PWD/ql:/ql/data -p 5700:5700 –name qinglong –hostname qinglong –restart unless-stopped whyour/qinglong:latest

    NodeJs 下:

    ts-md5
    @types/node
    prettytable
    node-telegram-bot-api
    tslib
    ql
    common
    fs
    typescript
    axios
    png-js
    axios
    ws@7.4.3
    crypto-js
    jieba
    global-agent
    jsdom -g
    moment
    form-data
    date-fns
    node-jsencrypt
    require
    js-base64
    tough-cookie
    json5
    jsdom
    dotenv
    qs

    Python3下:
    ping3
    canvas
    requests
    jieba
    PyExecJS
    httpx

    Linux下:

    lxml
    bizMsg
    bizCode
    gcc
    python-devel
    aiohttp
    magic

    常用命令

    查看容器名:docker ps -a

    重启青龙容器:docker restart 你的容器名

    更新青龙(或者直接面板更新):docker exec -it qinglong ql update

    更新青龙并编译:docker exec -it qinglong ql restart

    Jellyfin安装

    proxychains4 代理

    apt install proxychains4

    在添加Jellyfin源的地方有2个方式,如果用extrepo方式,就不必1到3步骤编号

    • root@server:~# apt update
    • root@server:~# apt install extrepo
    • root@server:~# extrepo enable jellyfin
    • # 1
    • root@server:~# apt update root@server:~# apt install curl gnupg
    • # 2
    • root@server:~# mkdir /etc/apt/keyrings
    • root@server:~# curl -fsSL https://repo.jellyfin.org/$( awk -F’=’ ‘/^ID=/{ print $NF }’ /etc/os-release )/jellyfin_team.gpg.key | gpg –dearmor -o /etc/apt/keyrings/jellyfin.gpg # 3
    • root@server:~# cat <<EOF | tee /etc/apt/sources.list.d/jellyfin.sources
    • Types: deb
    • URIs: https://repo.jellyfin.org/$( awk -F’=’ ‘/^ID=/{ print $NF }’ /etc/os-release ) Suites: $( awk -F’=’ ‘/^VERSION_CODENAME=/{ print $NF }’ /etc/os-release )
    • Components: main
    • Architectures: $( dpkg –print-architecture )
    • Signed-By: /etc/apt/keyrings/jellyfin.gpg
    • EOF

    添加源后,就可以更新,安装Jellyfin

    • # 4 root@server:~# apt update
    • root@server:~# apt install jellyfin
    • # 5 重启Jellyfin
    • root@server:~# systemctl restart jellyfin
    • # 6 关闭Jellyfin
    • root@server:~# systemctl stop jellyfin
    • # 7 启动Jellyfin
    • root@server:~# systemctl start jellyfin
    • # 8 开机启动Jellyfin
    • root@server:~# systemctl enable jellyfin

    配置Nginx的反向代理,需要修改配置DNS指向,配置域名证书,在路由器上配置端口转发到内部的IP端口即可。

    server {
    listen 443 ssl;
    server_name 你的域名;

    client_max_body_size 100M;
    
    
    ssl_certificate /root/certs/域名证书.cer;
    ssl_certificate_key /root/certs/域名证书.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers 'TLS-CHACHA20-POLY1305-SHA256:TLS-AES-256-GCM-SHA384:TLS-AES-128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
    ssl_prefer_server_ciphers on;    
    
    
    
    
    location / {
        proxy_pass http://127.0.0.1:8096;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Protocol $scheme;
        proxy_set_header X-Forwarded-Host $http_host;
    
        # Disable buffering when the nginx proxy gets very resource heavy upon streaming
        proxy_buffering off;
    }
    
    location = /web/ {
        proxy_pass http://127.0.0.1:8096/web/index.html;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Protocol $scheme;
        proxy_set_header X-Forwarded-Host $http_host;
    }
    
    location /socket {
        proxy_pass http://127.0.0.1:8096;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Protocol $scheme;
        proxy_set_header X-Forwarded-Host $http_host;
    }

    }