Giter Site home page Giter Site logo

blog's People

Contributors

dalaolala avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

blog's Issues

搭建web版的ssh终端

这里说一下简易版的如何搭建

项目的地址是这个
https://github.com/huashengdun/webssh

首先不推荐python2.7 最好用python3来部署

首先下载项目到本地

git clone https://github.com/huashengdun/webssh.git

安装必要的依赖,pip如果提示版本低,升级到最新版即可

pip3 install -r requirements.txt

启动,默认启动监听的是8888端口,

python3 run.py

如果要修改配置的的话,改这个文件

https://github.com/huashengdun/webssh/blob/master/webssh/settings.py

反向代理的配置,另外此处配置不支持别名,最好是用根域名

# Nginx config example
location / {
    proxy_pass http://127.0.0.1:8888;
    proxy_http_version 1.1;
    proxy_read_timeout 300;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Real-PORT $remote_port;
}

防止X-Forwarded-For伪造客户端IP漏洞,获取真实IP方法

HTTP协议是基于TCP协议的,由于getenv('REMOTE_ADDR')获取到的是TCP层直接连接的客户端的IP,对于Web应用服务器来说直接连接它的客户端实际上是Nginx,也就是TCP层是拿不到真实客户端的IP。

为了解决上面的问题,很多HTTP代理会在HTTP协议头中添加X-Forwarded-For头,用来追踪请求的来源。X-Forwarded-For的格式如下:

X-Forwarded-For: client1, proxy1, proxy2

php版本的代码如下

function get_ip()
    {
        $onlineip = '';
        if(getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) {
            $onlineip = getenv('HTTP_CLIENT_IP');
        } elseif(getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) {
            $onlineip = getenv('HTTP_X_FORWARDED_FOR');
        if (getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) {
            $onlineip = getenv('REMOTE_ADDR');
        } elseif (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {
            $onlineip = $_SERVER['REMOTE_ADDR'];
        }
        return $onlineip;
    }

在直接对外的Nginx反向代理服务器上配置:

proxy_set_header X-Forwarded-For $remote_addr;

这里使用$remote_addr替代上面的$proxy_add_x_forwarded_for。$proxy_add_x_forwarded_for会在原有X-Forwarded-For上追加IP,这就相当于给了伪造X-Forwarded-For的机会。而$remote_addr是获取的是直接TCP连接的客户端IP(类似于Java中的request.getRemoteAddr()),这个是无法伪造的,即使客户端伪造也会被覆盖掉,而不是追加。

需要注意的是,如果有多层代理,那么只要在直接对外访问的Nginx上配置X-Forwarded-For为$remote_addr,内部层的Nginx还是要配置为$proxy_add_x_forwarded_for,不然内部层的Nginx又会覆盖掉客户端的真实IP。

利用jsdelivr进行静态文件的cdn加速服务

jsdelivr官方提供了github托管的服务,
因此建一个项目,直接利用地址转换即可实现js文件的加速
注意有文件大小的限制,限制为20M

不建议用于图床加速,会导致账号异常的现象。

具体请参考如下项目,也可以直接fork,修改下github的用户名使用即可

https://github.com/dalaolala/cdnjs

官方的加速地址如下:
https://www.jsdelivr.com/?docs=gh

前端加速js文件汇总
https://51.ruyo.net/12387.html

centos手动挂载磁盘

挂载磁盘命令

fdisk -l
fdisk  /dev/sdb

然后依次输入

n->p->1->回车->回车->w

初始化磁盘

mkfs.xfs /dev/sdb

如果挂载失败是用强制格式化命令

mkfs.xfs -f /dev/sdb

对磁盘进行挂载

cd /
mkdir data
mount /dev/sdb  /data

挂载的目录自动启动

#查询磁盘分区的uuid 
sudo blkid

#设置开启自动挂载时使用
sudo vim /etc/fstab

加入:
UUID={uuid} /data xfs defaults 0 0

安装极简论坛Flarum

首先安装 Composer

curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer

全局配置(推荐)
可切换至国内阿里源,能解决无法下载或等待时间过长问题,主机存在于国外请具体视情况而定
切换阿里源:composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
取消配置:composer config -g --unset repos.packagist

后面可能会提示升级,按照提示进行升级即可

composer self-update

升级后降级的命令

composer self-update --1
composer self-update --2

创建好目录以后,在网站根目录安装论坛

composer create-project flarum/flarum . --stability=beta

相应的目录授权

chown -R www:www ./
chmod -R 775 public storage

在安装期间,您须将某些文件夹和目录权限升至为 755 或部分 775,
Beta 8+ 分别是 public 和 storage 文件夹
Beta 8- 分别是 assets 和 storage 文件夹
设置伪静态文件

location / {
    try_files $uri $uri/ /index.php?$query_string;
}
 
location /api {
    try_files $uri $uri/ /api.php?$query_string;
}
 
location /admin {
    try_files $uri $uri/ /admin.php?$query_string;
}
 
location /flarum {
    deny all;
    return 404;
}
 
location ~ .php$ {
    fastcgi_split_path_info ^(.+.php)(/.+)$;
    fastcgi_pass unix:/var/run/php5-fpm.sock;
    fastcgi_index index.php;
    include fastcgi_params;
}

php记得打开fileinfo扩展

参考以下内容

https://www.moerats.com/archives/240/
https://docs.flarum.org/zh/install.html
https://discuss.flarum.org.cn/d/1246

离线安装nginx和redis

1、nignx 离线安装

离线下载nginx

Nginx下载:https://pan.baidu.com/s/1hO4emswy_di-JBM-PHD1qg
提取码:kfvl

安装nginx软件

rpm -ivh nginx-1.12.0-1.el7.ngx.x86_64.rpm

相关文件和目录

默认放置网站文件的目录
/usr/share/nginx/html/

配置文件的目录
/etc/nginx/nginx.conf

如果我们要做的的配置很简单,不需要单独写,
我们可以注释掉配置文件的最后一行“include /etc/nginx/conf.d/*.conf;”,
直接写在当前配置文件即可,配置文件更改之后需重启Nginx才能生效

配置文件举例

server {
    listen       80;
    server_name  mynginxweb;
    location / {        #部署网站
         root /usr/share/nginx/html/myweb;
         index index.html index.htm;
    }
    location ^~ /api/ {		#代理一个地址
         proxy_pass http://192.168.0.101:8096/;
    }
}

2、redis 离线安装

下载相应的软件

http://download.redis.io/releases/redis-4.0.11.tar.gz

安装redis

copy 下载包到指定文件夹,依次执行命令
tar zxvf redis-4.0.11.tar.gz
cd ./redis-4.0.11/src
make 
make install

启动redis

./redis-server &

连接本机的redis

./redis-cli -h 127.0.0.1 -p 6379

启动和终止

1. 查找redis的进程号
ps -ef | grep redis
2. 停掉进程
kill -9 xxxx

设置密码

./redis-cli -h 127.0.0.1 -p 6379 
config set requirepass yangjiguanli123
auth yangjiguanli123

查询密码是否生效  config get requirepass

自建网页统计功能平台

可以用来代替百度统计或者谷歌统计

环境要求

A server with Node.js 12 or newer
A database (MySQL or Postgresql)

拉去代码并安装

git clone https://github.com/mikecao/umami.git
cd umami
npm install

新建数据并且导入数据库文件

数据库文件的目录在根目录下
sql/schema.mysql.sql

创建环境变量文件.env 写入数据库的配置

mysql://username:mypassword@localhost:3306/mydb

编译工程并启动

npm run build
npm start

问题解决

1、如果报错为如下

SWC Failed to Load  参考如下解决措施

https://nextjs.org/docs/messages/failed-loading-swc

新建 文件 .babelrc,写入下面内容,然后npm run build

{
  "presets": ["next/babel"]
}

2、pm2启动项目

pm2 start npm -- name umai -- start

3、反向代理设置

  location / { 
    proxy_pass http://127.0.0.1:3000; 
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $http_host;
   }   

4、默认的登录用户名和密码

admin /  umami

更多的内容以及参考如下

https://umami.is/docs/install

KeepAlive高可用配置

Keepalived

Keepalived是一个基于VRRP协议来实现的服务高可用方案。VRRP协议(虚拟路由冗余协议——
Virtual Router Redundancy Protocol,简称VRRP),是由IETF提出的解决局域网中配置静态网关
出现单点失效现象的路由协议,1998年已推出正式的RFC2338协议标准。VRRP广泛应用在边缘网络
中,它的设计目标是支持特定情况下IP数据流量失败转移不会引起混乱,允许主机使用单路由器,以
及即使在实际第一跳路由器使用失败的情形下仍能够维护路由器间的连通性。
大白话来说就是,VRRP协议允许一台机器可以拥有一个或者多个虚拟IP。在高可用的一组机器中,有
一个master,多个slave,对外提供一个虚IP,通过虚IP访问master,slave负责监控master,如果
master宕机,则选举其中一个slave接管master,虚IP绑定到新的master上(俗称IP漂移),从而实
现了高可用

关闭防火墙

setenforce 0
systemctl stop firewalld

安装Nginx(230与231)

sudo yum install ‐y yum‐utils

sudo cat >>/etc/yum.repos.d/nginx.repo<<‐'EOF'
[nginx‐stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
[nginx‐mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
EOF

#安装nginx
sudo yum install ‐y nginx

#启动nginx
systemctl start nginx

#系统启动nginx自动启动
systemctl enable nginx

KeepAlived Master(230)
安装keepalived
yum install ‐y keepalived

check_nginx脚本

Keepalived会定时执行“ps -C nginx --no-heading|wc -l ”命令,
如果返回0,代表Nginx挂了,然后尝试重启,如果重启失败,停止keepalived触发故障转移
如果返回大于0,代表Nginx正常运行,啥都不干~

sudo cat >/etc/keepalived/check_nginx.sh<<‐'EOF'
#!/bin/bash
counter=$(ps ‐C nginx ‐‐no‐heading | wc ‐l)
if [ "${counter}" = "0" ]; then
	systemctl start nginx
	sleep 2
	counter=$(ps ‐C nginx ‐‐no‐heading | wc ‐l)
	if [ "${counter}" = "0" ]; then
		systemctl stop keepalived
	fi
fi
EOF
chmod 755 /etc/keepalived/check_nginx.sh

keepalived.conf master配置文件

sudo cat >/etc/keepalived/keepalived.conf<<‐'EOF'
! Configuration File for keepalived
# 全局配置,路由ID,固定不变
global_defs {
router_id LVS_DEVEL
}
# 定义Nginx状态脚本
vrrp_script chk_nginx {
script "/etc/keepalived/check_nginx.sh"
# 间隔时间,单位为秒,默认1秒
interval 2
# 权重,当脚本成功或失败对当前节点的优先级是增加还是减少
weight ‐5
}
#VRRP实例
vrrp_instance VI_1 {
# 主节点
state MASTER
# 绑定的网卡,使用ifconfig命令查看获取
interface ens33
# 虚拟路由id,保证相同
virtual_router_id 51
# 优先级,抢占模式下优先级高的称为主
priority 101
# 指定发送VRRP通告的间隔。单位是秒。
advert_int 2
# 安全认证用的密码,自定义即可
authentication {
auth_type PASS
auth_pass 1111
}
# 对外暴露的VIP地址
virtual_ipaddress {
192.168.31.240
}
# 指定Nginx执行状态脚本
track_script {
chk_nginx
}
}
EOF

启动KeepAlived

systemctl start keepalived
tail ‐f /var/log/messages

一键搭建MTProto代理支持fake-TLS连接

一键搭建MTProto代理

docker run -d --network=host --name=tgproxy --restart=always seriyps/mtproto-proxy -p 端口号 -s [md5生成32位的字符串] -t [粘贴刚生成的TAG] -a dd -a tls

MD5生成个32位字符,比如这里可生成:https://www.cmd5.com
使用方式,用下面命令查询日志,然后复制倒数第二条链接就可以了

docker logs tgproxy

具体参数解释参考如下:

-p 443 / MTP_PORT=… proxy port
-s d0d6e111bada5511fcce9584deadbeef / MTP_SECRET=… proxy secret (don't append dd! it should be 32 chars long!)
-t dcbe8f1493fa4cd9ab300891c0b5b326 / MTP_TAG=… ad-tag that you get from @MTProxybot
-a dd / MTP_DD_ONLY=t only allow "secure" connections (dd-secrets)
-a tls / MTP_TLS_ONLY=t only allow "fake-TLS" connections (base64 secrets)

获取阿里云云盘的refresh_token

1、打开电脑网页

打开以下的网址 电脑打开这里

2、按一次F12键,进入浏览器开发者工具模式,点击工具上的 “Network” 菜单

3、找到位置 login.do?appName=aliyun链接,右键选 Copy 菜单里面的 Copy response 复制数据

4、打开 https://base64.us/ 解码 就可以看到了

NAT服务器开启并获取独立公网IPv6地址

CentOS7系统开启IPv6功能
有些镜像是禁用了IPv6功能的,因此需要开启。首先查看一下是否被禁用了

sysctl -a | grep ipv6.*disable

sysctl: reading key "net.ipv6.conf.all.stable_secret"

net.ipv6.conf.all.disable_ipv6 = 1

sysctl: net.ipv6.conf.default.disable_ipv6 = 1

reading key "net.ipv6.conf.default.stable_secret"

sysctl: reading key "net.ipv6.conf.eth0.stable_secret"

net.ipv6.conf.eth0.disable_ipv6 = 1

sysctl: reading key "net.ipv6.conf.lo.stable_secret"

net.ipv6.conf.lo.disable_ipv6 = 1

disable=1说明被禁用了,因此需要去修改,配置文件为/etc/sysctl.conf

vi /etc/sysctl.conf

把ipv6 disable的参数都改为0,然后保存,重载服务后生效
执行 sysctl -p

vm.swappiness = 0

net.ipv4.neigh.default.gc_stale_time = 120

net.ipv4.conf.all.rp_filter = 0

net.ipv4.conf.default.rp_filter = 0

net.ipv4.conf.default.arp_announce = 2

net.ipv4.conf.lo.arp_announce = 2

net.ipv4.conf.all.arp_announce = 2

net.ipv4.tcp_max_tw_buckets = 5000

net.ipv4.tcp_syncookies = 1

net.ipv4.tcp_max_syn_backlog = 1024

net.ipv4.tcp_synack_retries = 2

net.ipv6.conf.all.disable_ipv6 = 0

net.ipv6.conf.default.disable_ipv6 = 0

net.ipv6.conf.lo.disable_ipv6 = 0

设置网卡,启用DHCP
修改网卡配置文件:

vi /etc/sysconfig/network-scripts/ifcfg-eth0

在原有配置后面增加输入以下信息:

Networking_IPV6=yes
DHCPV6C=yes
IPV6INIT=yes

然后重启网络:

service network restart

centos7安装nginx无法读取证书报错解决

手动安装nginx,如果证书路径不在nginx目录下,报下面的错误,死活无法解决

nginx: [emerg] cannot load certificate SSL: error:0200100D:system library:fopen:Permission denied:fo

最后才知道是SELinux的原因,具体为啥就不管了,先关了再说

关闭的方法有两种

第一种,临时关闭

setenforce 0  

永久关闭,需要重启

修改/etc/selinux/config 文件

将SELINUX=enforcing改为SELINUX=disabled

docker常用命令集合

#安装以及启动docker


curl -sSL https://get.docker.com/ | sh
service docker restart

国内机器安装docker

curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun

#容器镜像删除
必须先停止再删除


docker stop $(docker ps -a -q) 
docker rm $(docker ps -a -q)
docker images
docker rmi <image id>

#上传镜像到hub docker
点这里申请一个docker hub 帐号,
1、登录到dockehub点击一下按钮:create —> create repository

2、为存在于本地的镜像打标签,命令如下:
docker tag /[:]
这里的tag不指定就是latest,例如:


docker tag aaa/imagesa bbb/imagesb:V1.0

3、在本地登录docker hub 帐号,命令如下:


root@master:~# docker  login
Username: lidnyun
Password:
Email: 邮箱地址
WARNING: login credentials saved in /root/.docker/config.json
Login Succeeded

4、push镜像,命令如下:

docker push <hub-user>/<repo-name>:<tag>
例如:
docker push bbb/imagesb:V1.0

5、下载镜像

docker pull bbb/imagesb:V1.0

#打包以及使用本地镜像


打包
docker save -o /root/demo.tar bbb/imagesb:V1.0
使用
docker load -i /root/demo.tar

#创建TG MTProto
创建后找 MTProto Admin Bot注册


docker run -d -p 443:443 --name=mtproto --ulimit nofile=98304:98304 --restart=always -v proxy-config:/data -e TAG=fa030b8ba9a6a099c45328d67889c76a  -e SECRET=fa030b8ba9a6a027c45328d67889c76a telegrammessenger/proxy:latest

#安装Docker-Compose


curl -L "https://github.com/docker/compose/releases/download/1.25.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod a+x /usr/local/bin/docker-compose
# 创建个软链接,以后用 dc 命令来代替 docker-compose
ln -s /usr/local/bin/docker-compose /usr/bin/dc

国内镜像安装参考如下

sudo curl -L https://get.daocloud.io/docker/compose/releases/download/1.24.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

#重新编译镜像文件

进入到镜像源码目录,然后执行
docker build -t bbb/gmirror:v1 .

#生成某搜索镜像


docker run -p 80:80 -d bohan/onemirror

另外附上一个常见命令集合点这里

#进入到docker里面的命令

sudo docker ps
sudo docker exec -it 775c7c9ee1e1 /bin/bash 

#进入docker后无法使用vim命令

apt-get update
apt-get install vim

#docker进入容器内部

docker exec -it alade /bin/bash

CF Worker搭建vless协议代理

1、复制如下代码到worker中

注意自己可修改uuid 具体搜索

3e036e57-4d74-469a-b312-b97b59680ec3

// ../node_modules/uuid/dist/esm-browser/regex.js
var regex_default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;

// ../node_modules/uuid/dist/esm-browser/validate.js
function validate(uuid) {
  return typeof uuid === "string" && regex_default.test(uuid);
}
var validate_default = validate;

// ../node_modules/uuid/dist/esm-browser/stringify.js
var byteToHex = [];
for (let i = 0; i < 256; ++i) {
  byteToHex.push((i + 256).toString(16).slice(1));
}
function unsafeStringify(arr, offset = 0) {
  return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
}
function stringify(arr, offset = 0) {
  const uuid = unsafeStringify(arr, offset);
  if (!validate_default(uuid)) {
    throw TypeError("Stringified UUID is invalid");
  }
  return uuid;
}
var stringify_default = stringify;

// vless-js/lib/vless-js.ts
var WS_READY_STATE_OPEN = 1;
function makeReadableWebSocketStream(ws, earlyDataHeader, log) {
  let readableStreamCancel = false;
  return new ReadableStream({
    start(controller) {
      ws.addEventListener("message", async (e) => {
        if (readableStreamCancel) {
          return;
        }
        const vlessBuffer = e.data;
        controller.enqueue(vlessBuffer);
      });
      ws.addEventListener("error", (e) => {
        log("socket has error");
        readableStreamCancel = true;
        controller.error(e);
      });
      ws.addEventListener("close", () => {
        try {
          log("webSocket is close");
          if (readableStreamCancel) {
            return;
          }
          controller.close();
        } catch (error2) {
          log(`websocketStream can't close DUE to `, error2);
        }
      });
      const { earlyData, error } = base64ToArrayBuffer(earlyDataHeader);
      if (error) {
        log(`earlyDataHeader has invaild base64`);
        safeCloseWebSocket(ws);
        return;
      }
      if (earlyData) {
        controller.enqueue(earlyData);
      }
    },
    pull(controller) {
    },
    cancel(reason) {
      log(`websocketStream is cancel DUE to `, reason);
      if (readableStreamCancel) {
        return;
      }
      readableStreamCancel = true;
      safeCloseWebSocket(ws);
    }
  });
}
function base64ToArrayBuffer(base64Str) {
  if (!base64Str) {
    return { error: null };
  }
  try {
    base64Str = base64Str.replace(/-/g, "+").replace(/_/g, "/");
    const decode = atob(base64Str);
    const arryBuffer = Uint8Array.from(decode, (c) => c.charCodeAt(0));
    return { earlyData: arryBuffer.buffer, error: null };
  } catch (error) {
    return { error };
  }
}
function safeCloseWebSocket(socket) {
  try {
    if (socket.readyState === WS_READY_STATE_OPEN) {
      socket.close();
    }
  } catch (error) {
    console.error("safeCloseWebSocket error", error);
  }
}
function processVlessHeader(vlessBuffer, userID) {
  if (vlessBuffer.byteLength < 24) {
    return {
      hasError: true,
      message: "invalid data"
    };
  }
  const version = new Uint8Array(vlessBuffer.slice(0, 1));
  let isValidUser = false;
  let isUDP = false;
  if (stringify_default(new Uint8Array(vlessBuffer.slice(1, 17))) === userID) {
    isValidUser = true;
  }
  if (!isValidUser) {
    return {
      hasError: true,
      message: "invalid user"
    };
  }
  const optLength = new Uint8Array(vlessBuffer.slice(17, 18))[0];
  const command = new Uint8Array(
    vlessBuffer.slice(18 + optLength, 18 + optLength + 1)
  )[0];
  if (command === 1) {
  } else if (command === 2) {
    isUDP = true;
  } else {
    return {
      hasError: true,
      message: `command ${command} is not support, command 01-tcp,02-udp,03-mux`
    };
  }
  const portIndex = 18 + optLength + 1;
  const portBuffer = vlessBuffer.slice(portIndex, portIndex + 2);
  const portRemote = new DataView(portBuffer).getInt16(0);
  let addressIndex = portIndex + 2;
  const addressBuffer = new Uint8Array(
    vlessBuffer.slice(addressIndex, addressIndex + 1)
  );
  const addressType = addressBuffer[0];
  let addressLength = 0;
  let addressValueIndex = addressIndex + 1;
  let addressValue = "";
  switch (addressType) {
    case 1:
      addressLength = 4;
      addressValue = new Uint8Array(
        vlessBuffer.slice(addressValueIndex, addressValueIndex + addressLength)
      ).join(".");
      break;
    case 2:
      addressLength = new Uint8Array(
        vlessBuffer.slice(addressValueIndex, addressValueIndex + 1)
      )[0];
      addressValueIndex += 1;
      addressValue = new TextDecoder().decode(
        vlessBuffer.slice(addressValueIndex, addressValueIndex + addressLength)
      );
      break;
    case 3:
      addressLength = 16;
      const dataView = new DataView(
        vlessBuffer.slice(addressValueIndex, addressValueIndex + addressLength)
      );
      const ipv6 = [];
      for (let i = 0; i < 8; i++) {
        ipv6.push(dataView.getUint16(i * 2).toString(16));
      }
      addressValue = ipv6.join(":");
      break;
    default:
      console.log(`invild  addressType is ${addressType}`);
  }
  if (!addressValue) {
    return {
      hasError: true,
      message: `addressValue is empty, addressType is ${addressType}`
    };
  }
  return {
    hasError: false,
    addressType,
    addressRemote: addressValue,
    portRemote,
    rawDataIndex: addressValueIndex + addressLength,
    vlessVersion: version,
    isUDP
  };
}

// index.ts
import { connect } from "cloudflare:sockets";

// dns.ts
var doh = "https://cloudflare-dns.com/dns-query";
var dns = async (domain) => {
  const response = await fetch(`${doh}?name=${domain}`, {
    method: "GET",
    headers: {
      "Accept": "application/dns-json"
    }
  });
  const data = await response.json();
  const ans = data?.Answer;
  return ans?.find((record) => record.type === 1)?.data;
};
var isCloudFlareIP = (ip) => {
  const CFIP = [
    [2918526976, -4096],
    [1729491968, -1024],
    [1729546240, -1024],
    [1730085888, -1024],
    [2372222976, -16384],
    [1822605312, -16384],
    [3193827328, -4096],
    [3161612288, -4096],
    [3320508416, -1024],
    [3324608512, -32768],
    [2728263680, -131072],
    [1745879040, -524288],
    [1746403328, -262144],
    [2889875456, -524288],
    [2197833728, -1024]
  ];
  const isIp4InCidr = (ip2, cidr) => {
    const [a, b, c, d] = ip2.split(".").map(Number);
    ip2 = a << 24 | b << 16 | c << 8 | d;
    const [range, mask] = cidr;
    return (ip2 & mask) === range;
  };
  return CFIP.some((cidr) => isIp4InCidr(ip, cidr));
};

// index.ts
var HTML404 = "Script by zizifn, modified by MisakaNo";
function delay2(ms) {
  return new Promise((resolve, rej) => {
    setTimeout(resolve, ms);
  });
}
var workers_default = {
  async fetch(request, env, ctx) {
    let address = "";
    let portWithRandomLog = "";
    const userID = env.UUID || "3e036e57-4d74-469a-b312-b97b59680ec3";
    const log = (info, event) => {
      console.log(`[${address}:${portWithRandomLog}] ${info}`, event || "");
    };
    const upgradeHeader = request.headers.get("Upgrade");
    if (!upgradeHeader || upgradeHeader !== "websocket") {
      return new Response(HTML404, {
        status: 404,
        headers: new Headers({ "Content-Type": "text/html" })
      });
    }
    const webSocketPair = new WebSocketPair();
    const [client, webSocket] = Object.values(webSocketPair);
    const earlyDataHeader = request.headers.get("sec-websocket-protocol") || "";
    let remoteSocket = null;
    webSocket.accept();
    const readableWebSocketStream = makeReadableWebSocketStream(
      webSocket,
      earlyDataHeader,
      log
    );
    let vlessResponseHeader = new Uint8Array([0, 0]);
    let remoteConnectionReadyResolve;
    readableWebSocketStream.pipeTo(
      new WritableStream({
        async write(chunk, controller) {
          if (remoteSocket) {
            const writer2 = remoteSocket.writable.getWriter();
            await writer2.write(chunk);
            writer2.releaseLock();
            return;
          }
          const {
            hasError,
            message,
            portRemote,
            addressType,
            addressRemote,
            rawDataIndex,
            vlessVersion,
            isUDP
          } = processVlessHeader(chunk, userID);
          address = addressRemote || "";
          portWithRandomLog = `${portRemote} -- ${isUDP ? "udp " : "tcp "} `;
          if (isUDP && portRemote != 53) {
            controller.error("UDP proxy only enable for DNS which is port 53");
            webSocket.close();
            return;
          }
          if (hasError) {
            controller.error(message);
            webSocket.close();
            return;
          }
          vlessResponseHeader = new Uint8Array([vlessVersion[0], 0]);
          const rawClientData = chunk.slice(rawDataIndex);
          let queryip = "";
          if (addressType === 2) {
            queryip = await dns(addressRemote);
            if (queryip && isCloudFlareIP(queryip)) {
              queryip = "64.68.192." + Math.floor(Math.random() * 255);
            }
          }
          remoteSocket = connect({
            hostname: queryip ? queryip : addressRemote,
            port: portRemote
          });
          log(`connected`);
          const writer = remoteSocket.writable.getWriter();
          await writer.write(rawClientData);
          writer.releaseLock();
          remoteConnectionReadyResolve(remoteSocket);
        },
        close() {
          console.log(
            `[${address}:${portWithRandomLog}] readableWebSocketStream is close`
          );
        },
        abort(reason) {
          console.log(
            `[${address}:${portWithRandomLog}] readableWebSocketStream is abort`,
            JSON.stringify(reason)
          );
        }
      })
    );
    (async () => {
      await new Promise((resolve) => remoteConnectionReadyResolve = resolve);
      let count = 0;
      remoteSocket.readable.pipeTo(
        new WritableStream({
          start() {
            if (webSocket.readyState === WebSocket.READY_STATE_OPEN) {
              webSocket.send(vlessResponseHeader);
            }
          },
          async write(chunk, controller) {
            if (webSocket.readyState === WebSocket.READY_STATE_OPEN) {
              if (count++ > 2e4) {
                await delay2(1);
              }
              webSocket.send(chunk);
            } else {
              controller.error(
                "webSocket.readyState is not open, maybe close"
              );
            }
          },
          close() {
            console.log(
              `[${address}:${portWithRandomLog}] remoteConnection!.readable is close`
            );
          },
          abort(reason) {
            console.error(
              `[${address}:${portWithRandomLog}] remoteConnection!.readable abort`,
              reason
            );
          }
        })
      ).catch((error) => {
        console.error(
          `[${address}:${portWithRandomLog}] processWebSocket has exception `,
          error.stack || error
        );
        safeCloseWebSocket2(webSocket);
      });
    })();
    return new Response(null, {
      status: 101,
      webSocket: client
    });
  }
};
function safeCloseWebSocket2(ws) {
  try {
    if (ws.readyState !== WebSocket.READY_STATE_CLOSED) {
      ws.close();
    }
  } catch (error) {
    console.error("safeCloseWebSocket error", error);
  }
}
export {
  workers_default as default
};
//# sourceMappingURL=index.js.map

2、节点配置如下

协议:Vless
地址:CF优选IP / 域名
端口:80 或 CF 支持的 HTTPS 端口
UUID/密码:设置的UUID(如未设置则为 `3e036e57-4d74-469a-b312-b97b59680ec3`)
传输协议:ws
伪装域名:设置的 Workers 自定义域名
路径:/

由于目前worker自带域名已被X,建议使用自己的域名

协议:Vless
地址:CF优选IP / 自己的域名
端口:443 或 CF 支持的 HTTPS 端口
UUID/密码:设置的UUID(如未设置则为 `3e036e57-4d74-469a-b312-b97b59680ec3`)
传输协议:ws
伪装域名:自己的域名
路径:/
传输安全:TLS
跳过证书验证:true 或 false 都可以

参考文章
https://web.archive.org/web/20230526070655/https://blog.misaka.rest/2023/05/26/cf-wkrs-vless/

参考githun相关项目
https://github.com/zizifn/edgetunnel

cf worker域名具体的设置参考
#4

手动安装nginx+php7.2+OneManager

本文使用的方案是手动安装nginx+php7.2+OneManager

准备工作
准备一个纯净的vps,系统为ubuntu

手动安装nginx

apt install epel-release
apt install nginx

手动安装php7.2
更新php7.2的软件源

#添加GPG
wget -O /etc/apt/trusted.gpg.d/php.gpg https://mirror.xtom.com.hk/sury/php/apt.gpg

#安装apt-transport-https
apt-get install apt-transport-https

#添加sury软件源
sh -c 'echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list'

#更新软件源缓存
apt-get update

安装php 7.2

apt install php7.2-fpm php7.2-mysql php7.2-curl php7.2-gd php7.2-mbstring php7.2-xml php7.2-xmlrpc php7.2-zip php7.2-opcache -y

设置php

sed -i 's/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/' /etc/php/7.2/fpm/php.ini 

到这里就安装好了,更多的命令

systemctl restart php7.2-fpm  #重启
systemctl start php7.2-fpm  #启动
systemctl stop php7.2-fpm  #关闭
systemctl status php7.2-fpm  #检查状态

安装OneManager
新建网站安装目录

mkdir -p /www/aaaa

下载源代码,并放到网站目录

cd /www/aaaa
git clone https://github.com/qkqpttgf/OneManager-php.git
cd OneManager-php
mv * ../
chmod 666 config.php

nginx配置php的文件

vi /etc/nginx/conf.d/aaaa.conf

server {
        listen 80;
        server_name aaaa.com;
        index index.php;
        root /www/aaaa/;
        rewrite ^/(?!.well-known)(.*)$ /index.php?/$1 last;
        location ~ \.php$ {
            fastcgi_pass   unix:/run/php/php7.2-fpm.sock;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            include        fastcgi_params;
        }
}

通过二维码发布下载地址

完整的代码如下

 <html>

<head>
<title>我的第一个 HTML 页面</title>


<script type="text/javascript" src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script type="text/javascript" src="https://cdn.bootcdn.net/ajax/libs/layer/3.5.1/layer.js"></script>

 <script type="text/javascript">
  function share(){  
                $("#testimg").attr("src","https://api.pwmqr.com/qrcode/create/?url=https://www.baidu.com");
                layer.open({
                      type: 1,
                      skin: '', //样式类名
                      title:false,
                      offset: 'auto',
                      area: ['300px', '300px'], //宽高
                      closeBtn: 1, //不显示关闭按钮
                      shade: 0,
                      anim: 2,
                      shadeClose: true, //开启遮罩关闭
                      content: $("#shareDiv")
                    });

            }

 </script>


</head>

<body>
	 <div style="font-size: 0.2rem;text-align: center;" onclick="share()">
                     点我点我来下载吧
                    </div>
                    <div class="social-share1" style="text-align:center; display:none;" id="shareDiv">
                    <img id="testimg" style="float:right;cursor:pointer" alt="" width="300" height="300"/>  
                    </div> 


</body>

</html>

手动安装旧版本的v2ray

手动安装
下载并解压V2Ray程序
首先下载V2Ray的发行版程序,解压压缩包并查看目录中的文件.

wget https://github.com/v2ray/v2ray-core/releases/download/v4.22.1/v2ray-linux-64.zip
unzip v2ray-linux-64.zip
cd v2ray-linux-64
ll -a

如果无法下载可以去这里
https://github.com/dalaolala/blog/tree/master/soft

v2ray和v2ctl是V2Ray的主程序和控制程序. geoip.dat和geosite.dat是程序所需要数据文件. systemd和systemv两个目录中包含了用于生成服务的文件. 为了可以使用预先设置好的服务文件,需要把文件移动至正确位置.

将文件移动至正确位置
根据V2Ray的安装脚本,会自动在如下目录生成如下文件:
/usr/bin/v2ray/v2ray
/usr/bin/v2ray/v2ctl
/etc/v2ray/config.json
/usr/bin/v2ray/geoip.dat
/usr/bin/v2ray/geosite.dat
于是现在要做的就是将文件移动至相应位置:

mkdir /usr/bin/v2ray
cp v2ray /usr/bin/v2ray/v2ray
cp v2ctl /usr/bin/v2ray/v2ctl
cp geoip.dat /usr/bin/v2ray/geoip.dat
cp geosite.dat /usr/bin/v2ray/geosite.dat
mkdir /etc/v2ray/
cp vpoint_vmess_freedom.json /etc/v2ray/config.json

最后一条命令是将当前的vpoint_vmess_freedom.json配置文件复制到指定位置,并修改其为config.json.
由于V2Ray是不区分服务端和客户端的,同一个程序可以配置成服务器也可以配置成客户端,程序目录中的vpoint_vmess_freedom.json一般用于配置服务器,而vpoint_socks_vmess.json用于配置成为客户端.
根据你服务器端的配置来修改/etc/v2ray/config.json配置文件(如果安装过windows版,可以去该软件下导出配置文件,粘贴到此目录下)

生成V2Ray服务
为了使用方便,一般将V2Ray配置成 systemctl 服务,还记得程序目录中两个文件夹么,里面保存了systemd和systemv两种系统服务的服务文件,如果严格按照上面的位置存放文件,那么服务文件就不需要修改.使用如下命令将v2ray.service文件移动到/usr/lib/systemd/system目录,就可以生成V2Ray服务了:

cp ./systemd/v2ray.service /usr/lib/systemd/system

服务生成后,还需要手动添加一些文件,用于V2Ray程序运行时使用,具体命令如下:

mkdir /var/log/v2ray/
touch /var/log/v2ray/access.log
touch /var/log/v2ray/error.log
touch /var/run/v2ray.pid
systemctl start v2ray
systemctl status v2ray

现在V2Ray程序就已经正常运行并且已经成功添加至系统服务,之后就可以使用以下命令将其设置为系统自动启动:

systemctl enable v2ray

发一个Cloudfront最通用配置

这里说的通用配置是牺牲一些cdn的功能,不用自己多操心!
不管啥站点,配置上就好用!而不是这个打不开,那个无法跳转!

乌克兰免费域名注册

爲了避免欺诈者大规模注册域名,我们制定了一条规则:
一个用户每月最多只能注册3个域名。域名注册SMS授权,每个月只能用一部手机授权3个注册域名。
免费提供以下服务:
● 域名的注册和续期爲1年;
● 域名到期前仅四个月即可进行下一次续订。域管理员(注册人)有权在域委派截止日期之前的4个月内确认下一年的域续订;
● 域名续签长达10年

官方域名注冊商:https://www.nic.ua

域名注册非常简单,关键在于创建帐户时填写的电话号码一定要与Telegram(电报)绑定,因爲涉及域名激活。除非您拥有乌克兰、俄罗斯、白俄罗斯、哈萨克斯坦实体卡。 如果使用虚拟电话号码请先绑定Telegram(电报),国家无限制。.PP.UA域名使用Telegram(电报)激活即时生效,而使用手机接收激活码非即时。

域名激活机器人

请单击链接:https://telegram.me/ppuabot

激活步骤很简单,按照提示即可!

demo : https://lala.pp.ua

特别注意

如果发现没法激活,一定去邮箱里看看,有个确认的邮件!

续约方式


1、登录网页点renew 一年

2、手机号接收短信 到这里激活下就可以了https://apu.drs.ua/en/

宝塔跳过首页弹出的验证

找到下面的目录

/www/server/panel/BTPanel/static/js/index.js

屏蔽掉下面的代码

if (bind_user == 'XXXX') {
    //show_force_bind();
}

宝塔nginx手动配置反向代理

宝塔虽然支持一键反向代理,
但是经过尝试,总是不好用

干脆手动配置,直接修改配置文件
把配置文件里面的下面内容进行替换

    location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
    {
        expires      30d;
        error_log off;
        access_log /dev/null;
    }
    
    location ~ .*\.(js|css)?$
    {
        expires      12h;
        error_log off;
        access_log /dev/null; 
    }

替换成下面的

    location / 
    {
        proxy_redirect off;
        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_pass http://127.0.0.1:8181;
    }

    location ~ .*\.(php|jsp|cgi|asp|aspx|flv|swf|xml)?$
    {
        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 REMOTE-HOST $remote_addr;
        proxy_pass http://127.0.0.1:8181;
    
    }

poe网页转OpenAI接口镜像

说明

  • poe.com可以免费的试用ChatGPT的聊天服务,而且限制相对较少!
  • 但是它屏蔽了一些国家,必须科学访问。
  • 如何绕过科学,直接访问,而且能像使用openai官方接口一样用它
  • 本文主要解决以上问题。

1、登录poe.com ,然后F12 - Application -Cookies 找到 p-b 的 value,这个就是你的key

image

2、接口请求地址为 https://gpt.ping8.top 这个相当于OpenAI的地址

3、接下来就跟你用OpenAI的接口一样了

这里用 chatgpt-next-web 举例

docker run --name chat -d -p 4000:3000 \
   -e OPENAI_API_KEY="上面第一步获取到的key" \
   -e CODE="123456" \
   -e BASE_URL="https://gpt.ping8.top" \
   yidadaa/chatgpt-next-web

打开浏览器 https://ip:4000 设置里输入密码 123456 就能正常用了

20230708 更新

修复了上下文的问题,支持流式响应

更新docker镜像一键部署到自己的服务器

 docker run --name poeai -d -p 3000:3000 spectmm/poeai:v1.3

启动成功后,这样测试下:

curl -X POST \
     -H "Content-Type: application/json" \
     -H "Authorization: Bearer 这里写上面那个key" \
     -d '{"model": "gpt-3.5-turbo", "messages": [{"role": "user", "content": "hi!"}], "temperature": 0.7}' \
     http://127.0.0.1:3000/v1/chat/completions;

20230709 更新

更新了镜像,适配了 chatgpt-next-web的桌面版

桌面版下载地址
https://github.com/Yidadaa/ChatGPT-Next-Web/releases

写上域名和那个”key“就行

自己用docker镜像搭建的最好反代一下,用 ip:port 貌似不行

    location / {
    proxy_pass       http://127.0.0.1:3000;
    proxy_set_header Host      $http_host;
    }

image

20230722 更新

poe接口修改了参数导致报错,修复了这个问题
优化接口查询,其它看上面说明,用镜像的得把镜像删除重新拉一下

安装vless协议的v2ray

VMESS 相信大家都不陌生了,他是 V2RAY 的传输协议。
但是在 5 月 V2RAY 爆出新闻之后,很多大神们都在弄一个新的协议,最具代表的就是 VLESS 协议。

官方安装参考这里
https://github.com/v2fly/fhs-install-v2ray

安装curl

yum makecache
yum install curl

下载脚本执行

curl -O https://raw.githubusercontent.com/v2fly/fhs-install-v2ray/master/install-release.sh
curl -O https://raw.githubusercontent.com/v2fly/fhs-install-v2ray/master/install-dat-release.sh
bash install-release.sh
bash install-dat-release.sh

国内服务器执行

curl -O https://raw.githubusercontent.com/dalaolala/blog/master/vvv/a.sh
curl -O https://raw.githubusercontent.com/dalaolala/blog/master/vvv/a.sh

获取一个新的uuid
https://1024tools.com/uuid 复制其中一行 uuid

进入 /usr/local/etc/v2ray/ 目录,编辑 config.json 文件 将里面全部代码改为:

{
  "log": {
        "access": "/var/log/v2ray/access.log",
        "error": "/var/log/v2ray/error.log",
        "loglevel": "warning"
    },
  "inbounds": [
    {
    "port":你的端口,
      "listen": "127.0.0.1",
      "tag": "VLESS-in",
      "protocol": "VLESS",
      "settings": {
        "clients": [
          {
          "id":"你的 UUID",
            "alterId": 0
          }
        ],
            "decryption": "none"
      },
      "streamSettings": {
        "network": "ws",
        "wsSettings": {
          "path":"/cs" 
        }
      }
    }
  ],
  "outbounds": [
    {
      "protocol": "freedom",
      "settings": { },
      "tag": "direct"
    },
    {
      "protocol": "blackhole",
      "settings": { },
      "tag": "blocked"
    }
  ],
  "dns": {
    "servers": [
      "https+local://1.1.1.1/dns-query",
          "1.1.1.1",
          "1.0.0.1",
          "8.8.8.8",
          "8.8.4.4",
          "localhost"
    ]
  },
  "routing": {
    "domainStrategy": "AsIs",
    "rules": [
      {
        "type": "field",
        "inboundTag": [
          "VLESS-in"
        ],
        "outboundTag": "direct"
      }
    ]
  }
}

pip下载速度加速

任何一个信息都可以把人分为两类,知道的和不知道的。有些我们已知的信息,自己觉得很平常,却可能对另一些不知道的人来说很有用处。

比如今天要说的这个小技巧,我自己原以为不值一提,网上也很容易搜到。但当数次我把这个告诉别人后,对方惊呼“这么好用竟然之前不知道”的时候,我觉得还是有必要分享一下。哪怕再多让几个人知道,也是有好处的。

其实你只要加个参数 -i,可能就会让下载速度上升 10 倍,比如:

pip install django -i https://pypi.tuna.tsinghua.edu.cn/simple

另附常用的加速网址

清华
https://pypi.tuna.tsinghua.edu.cn/simple/

中科大
https://pypi.mirrors.ustc.edu.cn/simple/

阿里云
https://mirrors.aliyun.com/pypi/simple/

豆瓣
http://pypi.douban.com/simple/

docker一键安装酸酸乳网络加速

安装docker

curl -sSL https://get.docker.com/ | sh
service docker restart

curl -fsSL https://get.docker.com | bash
curl -L "https://github.com/docker/compose/releases/download/1.25.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod a+x /usr/local/bin/docker-compose
# 创建个软链接,以后用 dc 命令来代替 docker-compose
ln -s /usr/local/bin/docker-compose /usr/bin/dc

docker常用命令

docker stop $(docker ps -a -q) 
docker rm $(docker ps -a -q)
docker images
docker rmi <image id>

一键安装ss

docker run -dt --name ss --restart=always -p 6443:6443 mritd/shadowsocks -s "-s 0.0.0.0 -p 6443 -m chacha20-ietf-poly1305 -k test123" 

参数详解请参考这里

一键开启BBR加速

wget -N --no-check-certificate "https://raw.githubusercontent.com/chiakge/Linux-NetSpeed/master/tcp.sh"
chmod +x tcp.sh
./tcp.sh

如果不想docker可以使用如下

yum install shadowsocks-libev

echo "{
    "server":["0.0.0.0","[::]"],
    "mode":"tcp_and_udp",
    "server_port":2333,
    "password":"123",
    "timeout":60,
    "method":"chacha20-ietf-poly1305"
}" > /etc/shadowsocks-libev/config.json

systemctl enable shadowsocks-libev
systemctl restart shadowsocks-libev

frp透传内网的web服务

安装服务端

下载最新版本并安装到对应的目录

wget https://ghproxy.com/https://github.com/fatedier/frp/releases/download/v0.39.0/frp_0.39.0_linux_amd64.tar.gz
tar -zxvf frp_0.39.0_linux_amd64.tar.gz
mv frp_0.39.0_linux_amd64 frp

注册为服务

vim /etc/systemd/system/frp.service

服务内容如下,这里注意启动的路径要正确

[Unit]
Description=Frp Server Service
After=network.target

[Service]
Type=simple
ExecStart=/root/frpdemo/frps -c /root/frpdemo/frps.ini
TimeoutStartSec=0
KillMode=process
KillSignal=SIGTERM
Restart=on-failure
RestartSec=60s

[Install]
WantedBy=default.target
systemctl daemon-reload
systemctl  start frp

安装客户端

同服务端,服务启动路径和格式如下

/home/devops/frp/frpdemo/frpc -c /home/devops/frp/frpdemo/frpc.ini

配置文件

配置默认外网地址为8.8.8.8 内网地址为192.168.1.1
服务端frps.ini

[common]
#穿透的端口
bind_port = 7000
#http端口设置
vhost_http_port = 8047
#客户端连接令牌
token = mytoken
#https端口设置
#vhost_https_port=8047
#显示的日志级别
log_level = info
#https端口设置
#vhost_https_port=8047

客户端frpc.ini

[common]
server_addr = 8.8.8.8
server_port = 7000
token = mytoken

[web01]
type = http
local_ip =192.168.1.1
local_port =8080
custom_domains = 8.8.8.8

此时 访问 8.8.8.8:8047 就可以访问内网的192.168.1.1:8080

使用自定义绑定域名 实现 内网多 WEB 穿透。

[web00] 
type = http 
local_ip = 192.168.1.2 
local_port = 80 
custom_domains = xx0.domain_name 

[web01] 
type = http 
local_ip = 192.168.1.3
local_port = 81 
custom_domains = xx1.domain_name 

使用TCP端口多内网 穿透

[web00] 
type = tcp 
local_ip = 192.168.1.2
local_port = 80
remote_port = 40001 

[web01] 
type = tcp
local_ip = 192.168.1.3
local_port = 81 
remote_port = 40002 

基于宝塔搭建h5ai目录列表程序

可能是最全的h5ai搭建教程

1、下载和安装

官方的下载地址是这个 https://larsjung.de/h5ai/

如果使用宝塔的话,一定把【网站目录】里面的“防跨站攻击”关闭

修改配置文件
宝塔【配置文件】,找到index index.php index.html
改为index index.html index.php /_h5ai/public/index.php

修改前


server
{
    listen 80;
    ...
    index index.php index.html index.htm default.php default.htm default.html;
    ...

修改后


server
{
    listen 80;
    ...
    index  index.html  index.php  /_h5ai/public/index.php;
    ...

2、使用指南

把相应的文件上传到网站根目录,和_h5ai同一个目录即可。

需要注意的是,在虚拟主机根目录下,如果有 index.html 的话
(一些面板可能会放置一个默认的 index.html 文件),
请将其删除,否则不显示虚拟主机下的任何目录及文件。

├── _h5ai
│ ├── CHANGELOG.md
│ ├── private
│ ├── public
│ └── README.md
├── 您要显示的文件夹
│ ├── 子文件夹1
│ ├── 文件1
│ └── 文件2
└── 您要显示的文件夹
├── 文件1
└── 文件2

3、进阶教程

  • 查看全部功能开放情况
    访问你的域名xxxx.com/_h5ai/public/index.php(初始密码为空)
  • Use EXIF thumbs安装
    宝塔用户可直接在后台点击php版本,安装扩展 -> exif 一键安装即可
  • Movie thumbs (ffmpeg)安装

CentOS 6&7安装ffmpeg
CentOS 6和7安装方法是不一样的,下面分别说明:

安装前都需要先安装epel扩展源

yum -y install epel-release

CentOS 6比较简单,安装yum源之后直接安装即可:

su -c 'yum localinstall --nogpgcheck https://download1.rpmfusion.org/free/el/rpmfusion-free-release-6.noarch.rpm https://download1.rpmfusion.org/nonfree/el/rpmfusion-nonfree-release-6.noarch.rpm'

yum -y install ffmpeg ffmpeg-devel

而CentOS 7需额外安装扩展源:

su -c 'yum localinstall --nogpgcheck https://download1.rpmfusion.org/free/el/rpmfusion-free-release-7.noarch.rpm https://download1.rpmfusion.org/nonfree/el/rpmfusion-nonfree-release-7.noarch.rpm'

rpm --import http://li.nux.ro/download/nux/RPM-GPG-KEY-nux.ro
rpm -Uvh http://li.nux.ro/download/nux/dextop/el7/x86_64/nux-dextop-release-0-1.el7.nux.noarch.rpm

yum -y install ffmpeg ffmpeg-devel
  • PDF thumbs安装

yum -y install ImageMagick
  • Public Cache directory和Private Cache directory

把h5ai程序_h5ai中private和public两个文件夹中的cache目录权限设置为777,
刷新一下网页可以看到两个no变为yes了。
  • Shell tar,Shell zip和Shell du

在php.ini被禁用函数中去掉exec和passthru即可
把scandir函数去掉禁用,不然会出现无非显示目录中文件

4、优化访问速度

h5ai引用了谷歌的字体库,所以访问会很慢
这个文件 /_h5ai/private/conf/options.json
第26行找到下面文件替换如下:
fonts.googleapis.com为fonts.geekzu.org

5、设置用户名和密码

找到 _h5ai/public/index.php 在上方加入下面代码

 auth();
function auth ()
{
        $valid_passwords = array ("1" => "1");
        $valid_users = array_keys($valid_passwords);

        $user = $_SERVER['PHP_AUTH_USER'];
        $pass = $_SERVER['PHP_AUTH_PW'];

        $validated = (in_array($user, $valid_users)) && ($pass == $valid_passwords[$user]);

        if (!$validated) {
          header('WWW-Authenticate: Basic realm="My Realm"');
          header('HTTP/1.0 401 Unauthorized');
          die ("Not authorized");
        }
}

6、中文乱码

private\php\core\class-context.php (在文件private\php\core\class-context.php)

line 85 Replace as

$encoded_parts[] = rawurlencode(mb_convert_encoding($part, "UTF-8", "GBK"));

and line 94 Replace as

return Util::normalize_path($this->setup->get('ROOT_PATH') . '/' . mb_convert_encoding(rawurldecode($rel_href), "GBK", "UTF-8"));

7、效果图

gmail配置邮箱发信

之前发邮件总是失败很多次,总结一下,按照如下设置成功率比较高

1、在设置>转发和POP/IMAP中,勾选

  • 对所有邮件启用 POP
  • 启用 IMAP

gmail配置01

然后保存更改。

2、允许不够安全的应用

登录谷歌邮箱后,访问 谷歌权限设置界面 ,启用允许不够安全的应用。

gmail配置02

另外,若遇到提示

不允许访问账户

登录谷歌邮箱后,去 gmail的这个界面 点击允许。这种情况较为少见。


Linux常用的命令

增加交换分区512M

dd if=/dev/zero of=/root/swap bs=1024 count=512000
mkswap /root/swap
swapon /root/swap
echo "/root/swap swap swap defaults 0 0">> /etc/fstab

挂在磁盘

查看需要挂在的磁盘,这里比如是/dev/vdb
fdesk -l

挂载
mkdir -p /storage
mkfs.ext4 /dev/vdb
mount /dev/vdb /storage

防火墙

systemctl status firewalld.service		查看firewalld状态
systemctl start firewalld.service		开启firewalld
systemctl stop firewalld.service		关闭firewalld
firewall-cmd --zone=public --add-port=80/tcp --permanent	永久添加指定端口
firewall-cmd --zone=public --remove-port=8080/tcp --permanent	永久移除指定端口
firewall-cmd --query-port=3306/tcp		查看端口是否被开放,返回yes/no
firewall-cmd --list-all		查看所有开放的端口
systemctl enable firewalld.service		开启自启
systemctl disable firewalld.service		禁止开机自启
systemctl is-enabled firewalld.service		查看是否开机自启
firewall-cmd --reload		更新防火墙规则(立即生效,永久添加时需要reload)

查看大文件命令

find . -type f -size +800M  -print0 | xargs -0 du -h | sort -nr

查看当前目录文件的大小

du -h --max-depth=1 *

查看日志内容

less catalina.out

#常用命令
j    下一行
k    上一行
f    向下滚动一屏幕
b    向上滚动一屏幕
g    定位到文档头部
G    定位到文档最尾部
q    退出less模式

/keyword  向下查找
n    向下匹配下一处匹配文本
N    向上匹配下一处匹配文本

?keyword  向上查找
n    向上匹配下一处匹配文本
N    向下匹配下一处匹配文本

修改主机名称

hostnamectl set-hostname centos7.com 

修改定时任务

vi /etc/crontab

查看具体占用的端口号信息

netstat -ntulp |grep 5998

结束所有node相关的进程

ps -ef | grep node | grep -v grep | awk '{print "kill -9 "$2}' | sh

云函数部署python程序解决依赖的问题

这里以 pymysql依赖组件为例

首先要在代码中对依赖进行打包,注意要部署的文件要放在根目录

mkdir onedir
cd onedir

pip install -t . PyMySQL

#对当前包的内容进行打包
zip -r ondir.zip *

打完包直接上传zip包即可

进阶使用方法

如果本地打包不成功,建议直接拉取官方云函数的部署镜像,然后采用上面的办法

参考文档地址

https://cloud.tencent.com/document/product/583/50826

docker出现乱码问题

export  LANG="en_US.UTF-8"

安装依赖加速

pip install -t . PyMySQL -i https://pypi.tuna.tsinghua.edu.cn/simple

一键安装聊天工具fiora

首先是官方的安装方法,参考这里

https://yinxin630.github.io/fiora/zh-Hans/docs/install

提示:后面创建应用镜像的时候可能需要ctrl+c 结束掉,然后docker restart 镜像名 即可

这里对镜像做了一些定制化,主要是修改了聊天记录登录后可见, 去掉了版权等信息,官方的安装方法参考上面地址

docker pull mongo

docker pull redis

docker pull dalaolala/fiora:V1.0

docker network create fiora-network

docker run --name fioradb -p 27017:27017 --network fiora-network mongo

docker run --name fioraredis -p 6379:6379 --network fiora-network redis

docker run --name fiora -p 9200:9200 --network fiora-network -e Database=mongodb://fioradb:27017/fiora -e RedisHost=fioraredis dalaolala/fiora:V1.0

登陆以后,设置管理员账号,首先登到镜像中去

 docker exec -it fiora /bin/bash

新建.env 文件

apt-get update
apt-get install vim
vi .env

设置管理员账号同时禁止注册

Administrator=用户的ID
DisableRegister=true

几个常用的命令

#修改默认的群组,修改默认群组一定用这个命令,否则群组会自动消失
yarn script updateDefaultGroupName [newName]

#获取到用户的注册id
yarn script getUserId [username]

#注册新账号
yarn script register [username] [password]

一键DD常用的三个办法

很多情况下要换系统,比如一些机器装有监控之类

这里介绍三个方法,详细点击进去看即可

wget --no-check-certificate -O AutoReinstall.sh https://git.io/AutoReinstall.sh && bash AutoReinstall.sh

国内服务器

wget --no-check-certificate -O AutoReinstall.sh https://ghproxy.com/https://raw.githubusercontent.com/hiCasper/Shell/master/AutoReinstall.sh && bash AutoReinstall.sh

默认的登陆密码

CentOS:Pwd@CentOS
其他 Linux 系统:Pwd@Linux
附几个 Windows 镜像:

Windows Server 2019 Datacenter x64(密码:Password147)
Windows Server 2016 Datacenter x64(密码:Password147)
Windows Server 2012 R2 Datacenter x64(密码:Password147)

方法二在这里

wget --no-check-certificate -qO ~/Network-Reinstall-System-Modify.sh 'https://www.cxthhhhh.com/CXT-Library/Network-Reinstall-System-Modify/Network-Reinstall-System-Modify.sh' && chmod a+x ~/Network-Reinstall-System-Modify.sh && bash ~/Network-Reinstall-System-Modify.sh -UI_Options

方法三在这里

方法四

https://github.com/netbootxyz/netboot.xyz

方法五

https://github.com/dalaolala/blog/tree/master/ios

方法六

https://dd.wx.mk/

方法七

2023年10月更新
https://github.com/leitbogioro/Tools

方法八

2023年11月更新
https://github.com/bin456789/reinstall

docker一键安装svn

svn简介
SVN是Subversion的简称,是一个开放源代码的版本控制系统,相较于RCS、CVS,它采用了分支管理系统,它的设计目标就是取代CVS。互联网上很多版本控制服务已从CVS迁移到Subversion。说得简单一点SVN就是用于多个人共同开发同一个项目,共用资源的目的。

svn的docker搭建方法
请提前在服务器安装好docker服务
本篇教程选用的docker镜像为garethflowers/svn-server
安装并启动容器代码

docker run --restart always --name svn -d -v /root/dockers/svn:/var/opt/svn -p 3690:3690 garethflowers/svn-server

简析
/root/dockers/svn为宿主机的文件目录,/var/opt/svn为容器内的文件目录
--restart always命令可以实现容器在宿主机开机时自启动
-p 3690:3690表示将宿主机的3690端口映射到容器的3690端口,此端口为svn服务的默认端口,可以根据需要自行修改

创建svn仓库和账户
进入容器中进行配置

docker exec -it svn /bin/sh

创建名称为svn的资源仓库

svnadmin create svn

创建成功后svn目录内应该包含以下文件:
README.txt conf db format hooks locks
资源仓库配置,修改svnserve.conf

anon-access = none             # 匿名用户不可读写,也可设置为只读 read
auth-access = write            # 授权用户可写
password-db = passwd           # 密码文件路径,相对于当前目录
authz-db = authz               # 访问控制文件
realm = /var/opt/svn/svn       # 认证命名空间,会在认证提示界面显示,并作为凭证缓存的关键字,可以写仓库名称比如svn

配置账号与密码,修改 passwd文件,格式为“账号 = 密码”

[users]
# harry = harryssecret
# sally = sallyssecret
admin = 123456

配置账户权限,修改 authz文件

[groups]
owner = admin
[/]               # / 表示所有仓库
admin = rw        # 用户 admin 在所有仓库拥有读写权限
[svn:/]           # 表示以下用户在仓库 svn 的所有目录有相应权限
@owner = rw       # 表示 owner 组下的用户拥有读写权限

拉取svn

svn co svn://127.0.0.1:3690/svn

v2ray 进阶配置 ws+tls+nginx+cf

首先,你需要准备一个域名添加A记录解析到你的服务器,
可以去freenom免费注册,或者直接购买一个便宜的域名。

安装V2Ray

这里使用的是centos7系统
1、首先更新下系统:

yum -y update

2、安装V2Ray:

bash <(curl -L -s https://install.direct/go.sh)

3、设置开启启动

systemctl enable v2ray

安装SSL证书

这里说一下,如果要使用cf的full模式 ,可以用自签名的证书
安装EPEL:

yum -y install epel-release

安装certbot用于签发SSL证书:

yum -y install certbot

申请SSL证书:

certbot certonly --standalone -d example.com

这里的example.com替换成你的域名
如果申请成功,证书和私钥路径如下:

/etc/letsencrypt/live/example.com/fullchain.pem
/etc/letsencrypt/live/example.com/privkey.pem

配置Nginx

添加一个Nginx安装源:

vi /etc/yum.repos.d/nginx.repo

开启编辑模式,写入:

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1

写入完按ESC,然后输入:wq,按回车保存退出
安装Nginx:

yum -y install nginx

设置开机启动:

systemctl enable nginx

新建一个Nginx站点配置文件:

vi /etc/nginx/conf.d/v2ray.conf

写入配置

server {
    listen       443 ssl;
    server_name  example.com;

    ssl_certificate    /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key    /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    error_page 497  https://$host$request_uri;

location /ray {
    proxy_pass       http://127.0.0.1:10000;
    proxy_redirect             off;
    proxy_http_version         1.1;
    proxy_set_header Upgrade   $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host      $http_host;
    }
}

其中443是网站端口同时也是V2Ray传输端口,
127.0.0.1:10000其中的10000是监听端口,可以自行更改,
然后防火墙放行所需端口,或者直接关闭防火墙

配置V2Ray服务端

备份一下v2ray的默认配置文件:

cp /etc/v2ray/config.json /etc/v2ray/config.jsonbak

清空配置文件的内容:

echo "" > /etc/v2ray/config.json

编辑配置文件:

vi /etc/v2ray/config.json

写入

{
  "inbounds": [
    {
      "port": 10000,
      "listen":"127.0.0.1",
      "protocol": "vmess",
      "settings": {
        "clients": [
          {
            "id": "你的UUID",
            "alterId": 64
          }
        ]
      },
      "streamSettings": {
        "network": "ws",
        "wsSettings": {
        "path": "/ray"
        }
      }
    }
  ],
  "outbounds": [
    {
      "protocol": "freedom",
      "settings": {}
    }
  ]
}

UUID可以用这个网站生成:https://www.uuidgenerator.net
全部完成之后,关闭系统防火墙或者自行更改配置:

systemctl stop firewalld.service

同时把SELinux也关了:

vi /etc/selinux/config
SELINUX=disabled
setenforce 0

启动v2ray和nginx:

systemctl start v2ray
systemctl start nginx

套用cloudflare的cdn

申请好的域名指向服务器实际地址
然后开启FULL模式即可

上传本地代码到github私人仓库

如何把本地代码备份到上面呢,
其实还是挺简单的

1、去github上创建一个私人仓库

2、建立git仓库cd到你的本地项目根目录下,执行git命令,此命令会在当前目录下创建一个.git文件夹

git init

3、将add的文件commit到仓库,注意最后有个点

git add .

4、将add的文件commit到仓库

git commit -m "first commit"

如果第一次上传,关联邮箱和名称


git config --global user.email "*[email protected]"
git config --global user.name "yourname"

5、关联远程上传的地址


git remote add origin https://github.com/sina/weibo

6、提交本地代码

git push -u origin master -f 

7、上传本地单独修改的文件

git status
git add <file>
git commit -m “modify”
git pull
git push

8、git 放弃本地修改 强制更新

git fetch --all
git reset --hard origin/master

单条命令执行

git fetch --all && git reset --hard origin/master && git pull

使用V2搭建Socks5代理

1、安装v2ray

bash <(curl -L -s https://install.direct/go.sh)

service v2ray start   //启动v2ray
service v2ray stop    //停止v2ray
service v2ray restart     //重新启动v2ray

####2、 相关配置
相关的配置文件在 /etc/v2ray/config.json

{
"inbounds": [
    {
    "protocol": "socks",
    "port": 12345,
    "settings": {
        "auth": "password",
        "accounts": [
        {
            "user": "test",
            "pass": "password"
        }
        ],
        "udp": false,
        "ip": "127.0.0.1",
        "userLevel": 0
    }
    }
],
"outbounds": [
    {
    "protocol": "freedom",
    "settings": {}
    },
    {
    "protocol": "blackhole",
    "settings": {},
    "tag": "blocked"
    }
],
"routing": {
    "rules": [
    {
        "type": "field",
        "ip": ["geoip:private"],
        "outboundTag": "blocked"
    }
    ]
}
}

说明

socket5代理本身没有什么卵用,很容易识别!
但是用国内的nat机来转发到国外的vmess或者ss协议还是很合适的

上面配置中:

  • Socks 协议的认证方式,支持"noauth"匿名方式和"password"用户密码方式。
  • 只有当 auth 为 password 时,用户名和密码才有效。
  • 如果不需要用户名和密码,将 auth 设置为 noauth

利用s5中转到tls+ws+nginx配置

小提示:可以参考v2rayNG的配置文件

{
  "policy": {
    "system": {
      "statsInboundUplink": true,
      "statsInboundDownlink": true
    }
  },
  "log": {
    "access": "",
    "error": "",
    "loglevel": "warning"
  },
  "inbounds": [
    {
      "tag": "proxy",
      "port": 10082,
      "listen": "0.0.0.0",
      "protocol": "socks",
      "sniffing": {
        "enabled": true,
        "destOverride": [
          "http",
          "tls"
        ]
      },
      "settings": {
        "auth": "password",
		"accounts": [
        {
            "user": "test",
            "pass": "test"
        }
        ],
        "udp": true,
        "ip": null,
        "address": null,
        "clients": null
      },
      "streamSettings": null
    },
    {
      "tag": "api",
      "port": 53984,
      "listen": "127.0.0.1",
      "protocol": "dokodemo-door",
      "sniffing": null,
      "settings": {
        "auth": null,
        "udp": false,
        "ip": null,
        "address": "127.0.0.1",
        "clients": null
      },
      "streamSettings": null
    }
  ],
  "outbounds": [
    {
      "tag": "proxy",
      "protocol": "vmess",
      "settings": {
        "vnext": [
          {
            "address": "xx.xx.com",
            "port": 443,
            "users": [
              {
                "id": "000001ae-7dd7-4c77-96cc-e5b55a800000",
                "alterId": 64,
                "email": "[email protected]",
                "security": "auto"
              }
            ]
          }
        ],
        "servers": null,
        "response": null
      },
      "streamSettings": {
        "network": "ws",
        "security": "tls",
        "tlsSettings": {
          "allowInsecure": true,
          "serverName": null
        },
        "tcpSettings": null,
        "kcpSettings": null,
        "wsSettings": {
          "connectionReuse": true,
          "path": "/ws",
          "headers": null
        },
        "httpSettings": null,
        "quicSettings": null
      },
      "mux": {
        "enabled": true
      }
    },
    {
      "tag": "direct",
      "protocol": "freedom",
      "settings": {
        "vnext": null,
        "servers": null,
        "response": null
      },
      "streamSettings": null,
      "mux": null
    },
    {
      "tag": "block",
      "protocol": "blackhole",
      "settings": {
        "vnext": null,
        "servers": null,
        "response": {
          "type": "http"
        }
      },
      "streamSettings": null,
      "mux": null
    }
  ],
  "stats": {},
  "api": {
    "tag": "api",
    "services": [
      "StatsService"
    ]
  },
  "dns": null,
  "routing": {
    "domainStrategy": "IPIfNonMatch",
    "rules": [
      {
        "type": "field",
        "port": null,
        "inboundTag": "api",
        "outboundTag": "api",
        "ip": null,
        "domain": null
      },
      {
        "type": "field",
        "port": null,
        "inboundTag": null,
        "outboundTag": "block",
        "ip": [
          "127.0.0.1"
        ],
        "domain": null
      }
    ]
  }
}

举一反三 可以用MTProto中转别的协议

{
  "log": {
    "access": "/var/log/v2ray/access.log",
    "error": "/var/log/v2ray/error.log",
    "loglevel": "warning"
  },
  "inbounds": [
    {
      "port": 8080,
      "protocol": "mtproto",
      "listen":"0.0.0.0",
      "tag" : "mtproto-in",
      "settings": {
        "users" : [{"secret":"secret"}]
      }
    }
  ],
  "outbounds": [
    {
      "tag": "proxy",
      "protocol": "vmess",
      "settings": {
        "vnext": [
          {
            "address": "serverhost",
            "port": serverport,
            "users": [
              {
                "id": "0800d1b0-ff44-44c3-b5ab-af1960a0b7c5",
                "alterId": 64,
                "email": "[email protected]",
                "security": "aes-128-gcm"
              }
            ]
          }
        ]
      },
      "streamSettings": {
        "network": "tcp"
      },
      "mux": {
        "enabled": true
      }
    },
    {
      "protocol": "mtproto",
      "settings": {},
      "tag": "mtproto-out",
      "proxySettings" : {
        "tag": "proxy"
      }
    }
  ],
  "dns": null,
  "routing": {
    "rules": [
      {
        "type": "field",
        "ip": ["geoip:private"],
        "outboundTag": "blocked"
      },
      {
        "type": "field",
        "inboundTag": ["mtproto-in"],
        "outboundTag": "mtproto-out"
      }
    ]
  }
}

在线翻译接口

function geturl($url){
        $headerArray =array("Content-type:application/json;","Accept:application/json");
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE); 
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, TRUE); 
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch,CURLOPT_HTTPHEADER,$headerArray);
        $output = curl_exec($ch);
        curl_close($ch);
        $output = json_decode($output,true);
        return $output;
}
function translate($word, $en = 'en')
    {
        if( empty($word) ) return '';
        $word = htmlspecialchars($word, ENT_NOQUOTES);
        $len = mb_strlen($word, 'UTF-8');
        $l = 5000; #单次最大翻译内容长度
            $url = 'https://translate.google.cn/translate_a/single?client=gtx&dt=t&ie=UTF-8&oe=UTF-8&sl=auto&tl='.$en.'&q=';
        $text = '';
        for($i = 0; $i < $len; $i += $l)
        {
            $fanyi = geturl($url.urlencode( mb_substr( $word, $i, $l, "UTF-8" ) ));
                        echo $url.urlencode( mb_substr( $word, $i, $l, "UTF-8" ) );
            if(!empty($fanyi['content']))
            {
                $json = json_decode($fanyi['content'], true);
                if(isset($json[0][0][0]) && !empty($json[0][0][0]))$text .= $json[0][0][0];
            }
        }
        return $text;
    }

Win2008更改远程桌面端口脚本


介绍
为了安全我们经常对windows的管理都会修改默认的远程连接端口(tcp 3389)为其他的端口,
要连接管理的windows机器一多,修改起来就比较烦琐,再加上修改防火墙,就更是麻烦,
而且修改出错可能把自己关在外面,无法登录系统 ,
所以此时你需要一个脚本工具一键修改端口,修改防火墙,备份修改前的注册表。

保存为bat文件,执行即可


@echo off
@echo [远程桌面端口修改]
 CLS
 MODE con: COLS=68 LINES=20
 :: MODE语句为设定窗体的宽和高

SetLocal EnableDelayedExpansion
 set/p d="输入新的远程桌面端口:"
 set port=%d%
 echo 将修改远程桌面端口为[%d%].
 echo 如果启用了的[系统防火墙] 或 [IPSec策略] 或 [TCP/IP筛选]以及
 echo 其他防护软件允许该[%d%]端口通过.否则有可能被关在系统外面,导致系统无法远程连接!!
 echo 按任意键继续操作...
 pause>nul
 set Str=0123456789ABCDEF
 :loop
 set/a y=%d%%%16
 set/a d=%d%%/16
 set y=!Str:~%y%,1!
 set e=%y%%e%
 if %d% geq 1 goto loop
 echo ------------------------------------------------------
 echo 正在创建注册表文件.
 ping -n 2 127.0.1>nul
 echo Windows Registry Editor Version 5.00> c:\Remote.reg
 echo [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\Wds\rdpwd\Tds\tcp]>> c:\Remote.reg
 echo "PortNumber"=dword:0000%e%>> c:\Remote.reg
 echo [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp]>> c:\Remote.reg
 echo "PortNumber"=dword:0000%e%>> c:\Remote.reg
 echo 正在导入注册表文件以更改系统默认设置.
 ping -n 2 127.0.1>nul
 regedit /s c:\Remote.reg
 del c:\Remote.reg && echo 临时文件已经删除.
 ping -n 2 127.0.1>nul
 echo ------------------------------------------------------

 echo 端口已经修改完毕(重启生效!),修改防火墙策略.
 netsh advfirewall firewall delete rule name="mstsc_port%port%"
 netsh advfirewall firewall add rule name="mstsc_port%port%" protocol=TCP dir=in localport="%port%" action=allow remoteip=
 echo 防火墙打开远程端口[%port%] 成功!
 echo 按任意键退出...
 pause>nul

centos7 升级到python3

目前python2已经完全不更新了
而且会莫名其妙出现各种各样的问题

下面是升级到python3的方法

1、手动安装

curl -O https://www.python.org/ftp/python/3.5.0/Python-3.5.0.tgz

tar xf Python-3.5.0.tgz
cd Python-3.5.0
./configure
make
sudo make install

提示没有gcc,则要先安装一下

yum install gcc gcc-c++ -y

如果提示出现 'Ignoring ensurepip failure: pip 7.1.2 requires SSL/TLS'

yum install openssl-devel

2、使用一键脚本安装

bash <(curl -sL https://python3.netlify.com/install.sh)

参考这里:https://github.com/Jrohy/python3-install

CloudFlare通过SaaS免费使用CNAME接入域名解析

介于网络坏境不同,很多人有需求在保留国内域名DNS服务器不改变的情况下,还能接入国外服务商比如CloudFlare的服务,使得国内外都能有较好的网络使用感受,以前通过CloudFlare Partner来实现CNAME接入的方式已经失效,好在最近传来好消息,CloudFlare更改了Cloudflare for SaaS的收费策略,每个账户可以有100个域名免费额度,这等于普通用户来说等于是白送。用了两天”CloudFlare SaaS” ,有一些简单体会,和大家聊一下

CloudFlare 官方公告:https://blog.cloudflare.com/waf-for-saas/

前提条件

1,需要有一个已经通过NS接入CF的域名,只用作设置回退源服务器,不对外显示,所以没有什么要求。

2,开通 Cloudflare for SaaS 服务,需要CF账户绑定信用卡。

如果对此有疑虑(怕被反撸),可以通过PayPal来绑定。

操作方法

1、如图,进入jkenc459456.ml 面板,新建一个A记录作为回退源,命名为back,

IP地址要填真正想访问的地址(想接入的地址),小黄云要打开。

image

2、如图,面板进入SSL/TLS——自定义主机名,在源服务器框填入我们刚才新加的A记录域名back.jkenc459456.ml ,点击add fallback origin,会显示:回退源状态(初始化),刷新页面变成:回退源状态(有效)。

image

3、点击上方“添加自定义主机名”,进入添加页面,自定义主机名框里填写真正想要接入的二级域名,比如叫 a.b.com,其他设置保持默认,如图。

image

4、添加成功后,出现如下界面,需要前往b.com的域名服务商那里设置,添加上2条TXT类型的解析,一条是证书验证一条是主机名验证。

image

5、b.com的TXT解析添加后,刷新很快就会出现有效的提示,至此设置就算成功了。

image

个人用法

每个人的需求场景不同,我简单说一下个人的用法。

b.com的域名设置里,使用CNAME分别解析2条线路给a.b.com,一条境外,一条境内,境外线路对应的值就是我们CF的回退源地址 back.jkenc459456.ml,境内线路对应的值就是国内服务商提供给你的CDN地址,这样就可以互不干扰的提供全球服务了,简单分线路的功能一般域名服务商都有免费提供。如图:

image

获取telegram的常用ip段

获取telegram的ip段
可以直接从这里获取

https://ipinfo.io/AS44907
https://ipinfo.io/AS59930
https://ipinfo.io/AS62041

从上面的地址可以知道,目前telegram的ip段为

149.154.160.0/22 
149.154.164.0/22
149.154.172.0/22 
91.108.4.0/22
91.108.20.0/22
91.108.56.0/22
91.108.8.0/22
95.161.64.0/20
91.108.12.0/22

下面分享一个v2ray客户端只代理telegram的配置

{
  "policy": {
    "system": {
      "statsInboundUplink": true,
      "statsInboundDownlink": true
    }
  },
  "log": {
    "access": "",
    "error": "",
    "loglevel": "warning"
  },
  "inbounds": [
    {
      "tag": "proxy",
      "port": 10082,
      "listen": "0.0.0.0",
      "protocol": "socks",
      "sniffing": {
        "enabled": true,
        "destOverride": [
          "http",
          "tls"
        ]
      },
      "settings": {
        "auth": "noauth",
        "udp": true,
        "ip": null,
        "address": null,
        "clients": null
      },
      "streamSettings": null
    },
    {
      "tag": "api",
      "port": 63222,
      "listen": "127.0.0.1",
      "protocol": "dokodemo-door",
      "sniffing": null,
      "settings": {
        "auth": null,
        "udp": false,
        "ip": null,
        "address": "127.0.0.1",
        "clients": null
      },
      "streamSettings": null
    }
  ],
  "outbounds": [
    {
      "tag": "proxy",
      "protocol": "vmess",
      "settings": {
        "vnext": [
          {
            "address": "youdomain.com",
            "port": 443,
            "users": [
              {
                "id": "c8efbe2b-95ef-3706-8012-7e78ddddd",
                "alterId": 2,
                "email": "[email protected]",
                "security": "auto"
              }
            ]
          }
        ],
        "servers": null,
        "response": null
      },
      "streamSettings": {
        "network": "ws",
        "security": "tls",
        "tlsSettings": {
          "allowInsecure": true,
          "serverName": "kr-node2.xtown.ru"
        },
        "tcpSettings": null,
        "kcpSettings": null,
        "wsSettings": {
          "connectionReuse": true,
          "path": "/v2ray",
          "headers": {
            "Host": "kr-node2.xtown.ru"
          }
        },
        "httpSettings": null,
        "quicSettings": null
      },
      "mux": {
        "enabled": true
      }
    },
    {
      "tag": "direct",
      "protocol": "freedom",
      "settings": {
        "vnext": null,
        "servers": null,
        "response": null
      },
      "streamSettings": null,
      "mux": null
    },
    {
      "tag": "block",
      "protocol": "blackhole",
      "settings": {
        "vnext": null,
        "servers": null,
        "response": {
          "type": "http"
        }
      },
      "streamSettings": null,
      "mux": null
    }
  ],
  "stats": {},
  "api": {
    "tag": "api",
    "services": [
      "StatsService"
    ]
  },
  "dns": null,
  "routing": {
    "domainStrategy": "IPIfNonMatch",
    "rules": [
      {
        "type": "field",
        "port": null,
        "inboundTag": "api",
        "outboundTag": "api",
        "ip": null,
        "domain": null
      },
      {
        "type": "field",
        "port": null,
        "inboundTag": null,
        "outboundTag": "proxy",
        "ip": [
          "149.154.160.0/22",
          "149.154.164.0/22",
          "149.154.172.0/22",
          "91.108.4.0/22",
          "91.108.20.0/22",
          "91.108.56.0/22",
          "91.108.8.0/22",
          "95.161.64.0/20",
          "91.108.12.0/22"
        ],
        "domain": null
      },
      {
        "type": "field",
        "port": null,
        "inboundTag": null,
        "outboundTag": "direct",
        "ip": null,
        "domain": [
          "google.com",
          "facebook.com",
          "youtube.com",
          "twitter.com",
          "instagram.com"
        ]
      },
      {
        "type": "field",
        "port": null,
        "inboundTag": null,
        "outboundTag": "direct",
        "ip": [
          "geoip:cn",
          "geoip:us",
          "geoip:gb"
        ],
        "domain": null
      }
    ]
  }
}

在 Heroku 搭建 V2Ray

1、首先注册账号

https://signup.heroku.com/login

2、部署应用

去这里,然后点击下面的部署按钮

https://github.com/dalaolala/v2ray-heroku

如下图所示

3、输入一个uuid (此处默认的也可以使用),默认的路径是/wss

4、部署完成以后获取给的二级域名

在应用里面找到【setting】,下面可以找到送的二级域名

这里如果要绑定自己的域名,需要绑定信用卡

但是也可以用cloudflare的反向代理(部署参考:https://github.com/dalaolala/blog/issues/4)

注意反向代理的配置用这个:

addEventListener(
  "fetch",event => {
     let url=new URL(event.request.url);
     url.hostname="应用名称.herokuapp.com";
     let request=new Request(url,event.request);
     event. respondWith(
       fetch(request)
     )
  }
)

5、另外可以部署多个app,然后客户端通过下面配置达到负载均衡效果

{
  "inbounds": [
    {
      "port": 1080,
      "listen": "127.0.0.1",
      "protocol": "socks",
      "sniffing": {
        "enabled": true,
        "destOverride": ["http", "tls"]
      },
      "settings": {
        "auth": "noauth",
        "udp": false
      }
    }
  ],
  "outbounds": [
    {
      "protocol": "vmess",
      "settings": {
        "vnext": [
          {
            "address": "1st.herokuapp.com",
            "port": 443,
            "users": [
              {
                "id": "40c98649-847b-412c-a229-5e68ca9985eb",
                "security": "auto",
                "alterId": 64
              }
            ]
          },
          {
            "address": "2nd.herokuapp.com",
            "port": 443,
            "users": [
              {
                "id": "40c98649-847b-412c-a229-5e68ca9985eb",
                "security": "auto",
                "alterId": 64
              }
            ]
          }
        ]
      },
      "streamSettings": {
        "network": "ws",
        "security": "tls"
      }
    }
  ]
}

cenot7安装go语言以及设置环境变量

  1. 下载go语言的安装包
wget https://studygolang.com/dl/golang/go1.22.1.linux-amd64.tar.gz
  1. 解压缩到指定文件夹
tar -C /usr/local -xzf go1.22.1.linux-amd64.tar.gz
  1. 设置环境变量
vi /etc/profile
export GOROOT=/usr/local/go
export PATH=$PATH:$GOROOT/bin
export GO111MODULE=on
export GOPROXY=https://goproxy.io

source /etc/profile
  1. 设置编译目录,需要编译文件放这里
mkdir -p /home/gopath
vi /etc/profile
export GOPATH=/home/gopath

纯ipv6 开启aapanel面板的域名访问

1、利用cloudflare加速,支持的端口如下

HTTP ports supported by Cloudflare:
80
8080
8880
2052
2082
2086
2095
HTTPS ports supported by Cloudflare:
443
2053
2083
2087
2096
8443

2、cloudflare的DNS面板增加一条AAAA记录到ipv6的地址

3、安装aapanel (参考官网)

4、修改端口号为步骤一中的任意端口,这里假设8443

5、开启面板的ipv6访问权限

touch /www/server/panel/data/ipv6.pl
echo "True" > /www/server/panel/data/ipv6.pl

6、重启面板

bt restart

7、直接访问即可

http://yourdomain:8443

如果无访访问,执行下面命令

rm -f /www/server/panel/data/admin_path.pl

8、一键安装wrap能够访问ipv4资源

bash <(curl -fsSL git.io/warp.sh) menu

利用cloudflare对任意的网站进行反代

代码库在这里

只需要修改index.js 即可

https://github.com/Siujoeng-Lau/Workers-Proxy/blob/master/src/index.js

这里说一下修改步骤

// 网页端要设置的域名.
const upstream = 'www.google.com'

// 移动端要设置的域名
const upstream_mobile = 'www.google.com'

// 要屏蔽的国家和区域.
const blocked_region = [ 'KP', 'SY', 'PK', 'CU']

// IP addresses which you wish to block from using your service.
const blocked_ip_address = ['0.0.0.0', '127.0.0.1']

使用cloudflare的Workers

【Create a Worker】然后复制上面的index.js内容即可

使用自定义域名

1、把域名接入cloudflare,此处步骤省略
2、设置子域名关联workers的【add route】
3、设置子域名的cname到workers给出的子域名(这个子域名可以自定义前缀)

3、设置要关联的子域名,此处一定要用这种格式,否则会不好用
youdomain.com/*

选择要使用的子域名以及workers

注意

cloudflare对workers的免费调用次数是有限制的

每天10万次,一般来讲,是足够用了

CloudFront自选IP完全手册

avatar
一、原理介绍
AWS提供CloudFront的CDN服务是不支持自选IP的,由于CloudFront边缘节点只提供东南亚导致速度十分捉鸡,甚至不如cloudflare提供的免费服务好用。
但某大佬意外发现可以通过类似于Cloudflare方式将备用域名Cname到cloudfrontCDN服务器的方式实现自选IP,且AWS在国内部署了不少的边缘节点(未开放),这就提供了一个可能,即通过自选IP的方式将域名DNS解析到AWS国内边缘节点,实现国内棉被CDN。

在实现这一操作中,面临以下几个问题:

1.如何找到AWS在国内的边缘节点
2.如何进行CDN侧的自选IP设置
3.如何实现自动push优选后的IP到DNS上

二、扫描AWS国内边缘节点
如果发送一个request到AWS边缘节点的https端口,返回的headers信息中,server会显示为CloudFront,而大部分都会是nginx或其他web服务器,可以以此作为区分。
avatar

1.扫描开放443端口的IP段
Cloudfront在国内的边缘节点肯定部署在IDC机房,但目前国内IDC机房所在的IP段与家宽基本混为一起,所以无法直接找到国内的IDC机房IP段,只能盲扫全国IP,好在Zmap扫描速度很快,我们要做的就是扫描IP段内所有开放了443端口的IP。
可以通过以下命令安装Zmap并扫描IP

  sudo apt-get install bison ed gawk gcc libc6-dev make
  sudo apt install zmap
  zmap -w iplist.txt -p 443 -B 30M -o ip-new.txt

2.扫描AWSCloudFront边缘节点
可以构造一个python脚本,使用脚本进行扫描,脚本从github抄的,核心代码很简单

#!/usr/bin/env python

#
coding = utf - 8# python2.7 only
import threading
import requests
import Queue
import sys
import re
import numpy as np#
def bThread(iplist):
    threadl = []
queue = Queue.Queue()
for host in iplist:
    queue.put(host)
for x in xrange(0, int(SETTHREAD)):
    threadl.append(tThread(queue))
for t in threadl:
    t.start()
for t in threadl:
    t.join()# create thread
class tThread(threading.Thread):
    def __init__(self, queue):
    threading.Thread.__init__(self)
self.queue = queue
def run(self):
    while not self.queue.empty():
    host = self.queue.get()
try:
checkServer(host)
except:
    continue
def checkServer(host):
    header = {
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36'
    }
aimurl = "http://" + host + ":443"
response = requests.get(url = aimurl, headers = header, timeout = 10)
serverText = response.headers['server']
if len(serverText) > 0:
    print "-" * 50 + "\n" + aimurl + "\nServer: " + serverText
if(serverText == "CloudFront"):
    if mutex.acquire(3):
    with open("result.txt", "a+") as file:
    file.write(host + "\n")
file.close()
mutex.release()
if __name__ == '__main__':
    print '\n############# Cloud Front Scan ################'
print ' Author hostloc.com'
print '################################################\n'
global SETTHREAD
global mutex
mutex = threading.Lock()
try:
SETTHREAD = sys.argv[2]
filepath = sys.argv[1]
with open(filepath, "r") as f:
    iplist = f.read().splitlines()# iplist = ip_range(sys.argv[1].split(
        '-')[0], sys.argv[1].split('-')[1])
print '\n[Note] Will scan ' + str(len(iplist)) + " host...\n"
bThread(iplist)
except KeyboardInterrupt:
    print 'Keyboard Interrupt!'
sys.exit()

使用示例: python cfscan.py 443-ip.txt 200
其中 cfscan.py 为 脚本名、 443-ip.txt为包含了IP的txt文件 200为线程数(卡顿调小)

avatar
最后结果会输出为当前目录下的 result.txt文件,结果即为可以使用的自选IP.

小硬盘的vps手动清理日志

用这个命令可以查看

du -h /var/log

Linux也是和Windows一样,需要清理垃圾,
大盘鸡不用看了,不是那么必要;不过常规10G、5G的小鸡,有必要看看,被吃掉1~2G很常见。

这是系统默认的日志目录,如果不改SSH端口,和禁用密码登陆,必然会产生大量日志,btmp、syslog、auth.log这几个日志能大到占用G以上的空间。
但是你不能通过 rm -rf 命令来删除,因为日志的特殊性,在使用中,用rm -rf 删除只是标记,并不能释放空间,还得重启之后才真正释放空间。

你要用的是 echo 来清空日志,这样就可以马上释放被占用的空间
(当然日志你要觉得要看看,可以先备份)

echo > /var/log/btmp
echo > /var/log/syslog
echo > /var/log/auth.log

此外,即便你已经修改了SSH端口和禁用了密码登陆,没有上面3个日志占用空间,也会出现是 /var/log/journal 在吃硬盘,可以通过以下命令限制占用大小,下面100M就是限制日志最大为100M(可以根据你个人情况修改)

journalctl --vacuum-size=100M

如果你安装了宝塔,直接上去清理也是个不错的选择!

微信扫码提示在浏览器中打开的遮罩代码

由于微信的限制,应用文件在内置浏览器中下载全部被屏蔽掉,造成很多人用微信扫描二维码下载时点击下载按钮没反应,我想到的是做一个提示用户在浏览器中打开下载。 之前写过的两篇文章:微信打开网址添加在浏览器中打开提示 和 微信扫描打开APP下载链接提示代码优化,尽管已经做得很简单,但发现很多问这类问题的都是小白。 其实原来很简单,就是判断当前是在微信内置浏览器中,然后将默认隐藏的提示层显示出来。 第一步:判断微信的UA。

var ua = navigator.userAgent;
var isWeixin =  !!/MicroMessenger/i.test(ua);

第二步:引入默认隐藏层。

<a href="http://caibaojian.com/test.apk" id="JdownApp">点击下载APP</a>
<a href="http://caibaojian.com/test.apk" id="JdownApp2" class="btn-warn">点击下载APP2</a>
<div class="wxtip" id="JweixinTip">
<span class="wxtip-icon"></span>
<p class="wxtip-txt">点击右上角<br/>选择在浏览器中打开</p>
</div>

第三步:添加CSS样式

.wxtip{background: rgba(0,0,0,0.8); text-align: center; position: fixed; left:0; top: 0; width: 100%; height: 100%; z-index: 998; display: none;}
.wxtip-icon{width: 52px; height: 67px; background: url(weixin-tip.png) no-repeat; display: block; position: absolute; right: 20px; top: 20px;}
.wxtip-txt{margin-top: 107px; color: #fff; font-size: 16px; line-height: 1.5;}

第四步:点击按钮显示隐藏层,点击隐藏层关闭,总的JS代码如下:

function weixinTip(ele){
	var ua = navigator.userAgent;
	var isWeixin = !!/MicroMessenger/i.test(ua);
	if(isWeixin){
		ele.onclick=function(e){
			window.event? window.event.returnValue = false : e.preventDefault();
			document.getElementById('JweixinTip').style.display='block';
		}
		document.getElementById('JweixinTip').onclick=function(){
			this.style.display='none';
		}
	}
}
var btn1 = document.getElementById('JdownApp');//下载一
weixinTip(btn1);
var btn2 = document.getElementById('JdownApp2'); //下载二
weixinTip(btn2);

完整代码如下:



  |  
-- | --
  | <!doctype html>
  | <html lang="en">
  | <head>
  | <meta charset="UTF-8">
  | <meta name="viewport" content="width=device-width,initial-scale=1.0">
  | <title>dy2018</title>
  |  
  | <style type="text/css">
  | /*演示用,请勿引入项目中*/
  | *{margin:0; padding: 0;}
  | body{font:normal 14px/1.5 Arial,Microsoft Yahei; color:#333;}
  | .example{padding: 20px;}
  | .example p{margin: 20px 0;}
  | a{display: inline-block; background: #61B3E6; color:#fff; padding: 0 10px; border-radius: 4px; text-align: center; margin: 0 5px; line-height: 22px; font-size: 14px; text-decoration: none;}
  | a.btn-warn{background: #F0AD4E;}
  | a:hover{opacity: 0.8;}
  | /*核心css*/
  | .wxtip{background: rgba(0,0,0,0.8); text-align: center; position: fixed; left:0; top: 0; width: 100%; height: 100%; z-index: 998; display: none;}
  | .wxtip-icon{width: 52px; height: 67px; background: url(http://caibaojian.com/d/uploads/2016/01/weixin-tip.png) no-repeat; display: block; position: absolute; right: 30px; top: 20px;}
  | .wxtip-txt{padding-top: 107px; color: #fff; font-size: 16px; line-height: 1.5;}
  | </style>
  | </head>
  | <body>
  | <div class="example">
  | <p>浏览器中打开,然后点击下载APP。</p>
  | <a href="#" id="JdownApp">点击下载APP</a>
  | <a href="#" id="JdownApp2" class="btn-warn">点击下载APP</a>
  | <div class="wxtip" id="JweixinTip">
  | <span class="wxtip-icon"></span>
  | <p class="wxtip-txt">点击右上角<br/>选择在浏览器中打开</p>
  | </div>
  | </div>
  | <script type="text/javascript">
  | function weixinTip(ele){
  | var ua = navigator.userAgent;
  | var isWeixin = !!/MicroMessenger/i.test(ua);
  | if(isWeixin){
  | ele.onclick=function(e){
  | window.event? window.event.returnValue = false : e.preventDefault();
  | document.getElementById('JweixinTip').style.display='block';
  | }
  | document.getElementById('JweixinTip').onclick=function(){
  | this.style.display='none';
  | }
  | }
  | }
  | var btn1 = document.getElementById('JdownApp');//下载一
  | weixinTip(btn1);
  | var btn2 = document.getElementById('JdownApp2'); //下载二
  | weixinTip(btn2);
  | </script>
  | </body>
  | </html>


Onedrive+OneManager+Heroku+CFWorkers

准备工作:
1, Onedrive,或Sharepoint
这个大家有的,各种A1,E3,E5,世纪。(Sharepoint默认25T)
2, OneManager,Github地址:https://github.com/qkqpttgf/OneManager-php
基于各种无服务器的平台,比如Heroku、腾讯SCF、阿里FC、华为FG、百度CFC,配置都保存在其环境变量中,当然也可以装在VPS与空间里,不过为了一致,程序不固定储存onedrive的目录结构,缓存最多1小时
3, Heroku,最好需要注册2个帐号,注册与登录时需要魔法,平时操作时不需要
OneManager配置是保存在环境变量中的,所以不需要一直监控保活,Heroku免费套餐每月550小时,550小时/30天=18.33小时,每天只要访问时间段空出来24-18=6小时没有人访问,这一个月其实就足够使用了,但有些人的网站可能访问人比较多所以还没到月底就用光了。
当然,heroku也可绑卡达到1000小时,同时还能自定义域名。但,SSL却比较麻烦。
4, CF workers,免费的就好 部署参考 这里

部署程序、安装程序、绑定网盘:
1, 将OneManager一键部署到Heroku
2, 访问给定的herokuapp域名,正式安装好程序
3, 安装好后登录,在设置中绑定Onedrive或Sharepoint
4, 在设置中做些设定
5, 换一个Heroku帐号再安装一次(时长够用就无所谓)

重点:
在CF Workers中填入以下代码

// 单日
const SingleDay = '111.herokuapp.com'
// 双日
const DoubleDay = '222.herokuapp.com'
// 一切给CF代理,true/false
const CFproxy = true

// 由于heroku不绑卡不能自定义域名,就算绑卡后https也不方便
// 另外免费套餐每月550小时,有些人不够用
// 于是在CF Workers使用此代码,分单双日拉取不同heroku帐号下的相同网页
// 只改上面,下面不用动

addEventListener('fetch', event => {
    let nd = new Date();
    if (nd.getDate()%2) {
        host = SingleDay
    } else {
        host = DoubleDay
    }
    if (!CFproxy) {
        let url=new URL(event.request.url);
        if (url.protocol == 'http:') {
            url.protocol = 'https:'
            response = Response.redirect(url.href);
            event.respondWith( response );
        } else {
            url.hostname=host;
            let request=new Request(url,event.request);
            event.respondWith( fetch(request) )
        }
    } else {
        event.respondWith( fetchAndApply(event.request) );
    }
})

async function fetchAndApply(request) {
    let response = null;
    let url = new URL(request.url);
    if (url.protocol == 'http:') {
        url.protocol = 'https:'
        response = Response.redirect(url.href);
        return response;
    }
    url.host = host;

    let method = request.method;
    let body = request.body;
    let request_headers = request.headers;
    let new_request_headers = new Headers(request_headers);

    new_request_headers.set('Host', url.host);
    new_request_headers.set('Referer', request.url);

    let original_response = await fetch(url.href, {
        method: method,
        body: body,
        headers: new_request_headers
    });

    response = new Response(original_response.body, {
        status: original_response.status,
        headers: original_response.headers
    })

    return response;
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.