dalaolala / blog Goto Github PK
View Code? Open in Web Editor NEW用issue来写博客 和别人学的
License: MIT License
用issue来写博客 和别人学的
License: MIT License
这里说一下简易版的如何搭建
项目的地址是这个
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;
}
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官方提供了github托管的服务,
因此建一个项目,直接利用地址转换即可实现js文件的加速
注意有文件大小的限制,限制为20M
不建议用于图床加速,会导致账号异常的现象。
具体请参考如下项目,也可以直接fork,修改下github的用户名使用即可
https://github.com/dalaolala/cdnjs
官方的加速地址如下:
https://www.jsdelivr.com/?docs=gh
前端加速js文件汇总
https://51.ruyo.net/12387.html
挂载磁盘命令
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
首先安装 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下载:https://pan.baidu.com/s/1hO4emswy_di-JBM-PHD1qg
提取码:kfvl
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/;
}
}
http://download.redis.io/releases/redis-4.0.11.tar.gz
copy 下载包到指定文件夹,依次执行命令
tar zxvf redis-4.0.11.tar.gz
cd ./redis-4.0.11/src
make
make install
./redis-server &
./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
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
更多的内容以及参考如下
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
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
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
systemctl start keepalived
tail ‐f /var/log/messages
一键搭建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)
1、打开电脑网页
打开以下的网址 电脑打开这里
2、按一次F12键,进入浏览器开发者工具模式,点击工具上的 “Network” 菜单
3、找到位置 login.do?appName=aliyun链接,右键选 Copy 菜单里面的 Copy response 复制数据
4、打开 https://base64.us/ 解码 就可以看到了
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
手动安装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
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
注意自己可修改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
协议: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
准备工作
准备一个纯净的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的发行版程序,解压压缩包并查看目录中的文件.
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
爲了避免欺诈者大规模注册域名,我们制定了一条规则:
一个用户每月最多只能注册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();
}
宝塔虽然支持一键反向代理,
但是经过尝试,总是不好用
干脆手动配置,直接修改配置文件
把配置文件里面的下面内容进行替换
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;
}
1、登录poe.com ,然后F12 - Application -Cookies 找到 p-b 的 value,这个就是你的key
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 就能正常用了
修复了上下文的问题,支持流式响应
更新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;
更新了镜像,适配了 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;
}
poe接口修改了参数导致报错,修复了这个问题
优化接口查询,其它看上面说明,用镜像的得把镜像删除重新拉一下
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"
}
]
}
}
任何一个信息都可以把人分为两类,知道的和不知道的。有些我们已知的信息,自己觉得很平常,却可能对另一些不知道的人来说很有用处。
比如今天要说的这个小技巧,我自己原以为不值一提,网上也很容易搜到。但当数次我把这个告诉别人后,对方惊呼“这么好用竟然之前不知道”的时候,我觉得还是有必要分享一下。哪怕再多让几个人知道,也是有好处的。
其实你只要加个参数 -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/
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 stop $(docker ps -a -q)
docker rm $(docker ps -a -q)
docker images
docker rmi <image id>
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"
wget -N --no-check-certificate "https://raw.githubusercontent.com/chiakge/Linux-NetSpeed/master/tcp.sh"
chmod +x tcp.sh
./tcp.sh
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
下载最新版本并安装到对应的目录
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
[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
[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搭建教程
官方的下载地址是这个 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;
...
把相应的文件上传到网站根目录,和_h5ai同一个目录即可。
需要注意的是,在虚拟主机根目录下,如果有 index.html 的话
(一些面板可能会放置一个默认的 index.html 文件),
请将其删除,否则不显示虚拟主机下的任何目录及文件。
├── _h5ai
│ ├── CHANGELOG.md
│ ├── private
│ ├── public
│ └── README.md
├── 您要显示的文件夹
│ ├── 子文件夹1
│ ├── 文件1
│ └── 文件2
└── 您要显示的文件夹
├── 文件1
└── 文件2
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
yum -y install ImageMagick
把h5ai程序_h5ai中private和public两个文件夹中的cache目录权限设置为777,
刷新一下网页可以看到两个no变为yes了。
在php.ini被禁用函数中去掉exec和passthru即可
把scandir函数去掉禁用,不然会出现无非显示目录中文件
h5ai引用了谷歌的字体库,所以访问会很慢
这个文件 /_h5ai/private/conf/options.json
第26行找到下面文件替换如下:
fonts.googleapis.com为fonts.geekzu.org
找到 _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");
}
}
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"));
之前发邮件总是失败很多次,总结一下,按照如下设置成功率比较高
1、在设置>转发和POP/IMAP
中,勾选
然后保存更改。
2、允许不够安全的应用
登录谷歌邮箱后,访问 谷歌权限设置界面 ,启用允许不够安全的应用。
另外,若遇到提示
不允许访问账户
登录谷歌邮箱后,去 gmail的这个界面 点击允许。这种情况较为少见。
增加交换分区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
这里以 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
首先是官方的安装方法,参考这里
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]
很多情况下要换系统,比如一些机器装有监控之类
这里介绍三个方法,详细点击进去看即可
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
2023年10月更新
https://github.com/leitbogioro/Tools
2023年11月更新
https://github.com/bin456789/reinstall
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
首先,你需要准备一个域名添加A记录解析到你的服务器,
可以去freenom免费注册,或者直接购买一个便宜的域名。
这里使用的是centos7系统
1、首先更新下系统:
yum -y update
2、安装V2Ray:
bash <(curl -L -s https://install.direct/go.sh)
3、设置开启启动
systemctl enable v2ray
这里说一下,如果要使用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安装源:
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的默认配置文件:
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
申请好的域名指向服务器实际地址
然后开启FULL模式即可
如何把本地代码备份到上面呢,
其实还是挺简单的
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
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协议还是很合适的
上面配置中:
小提示:可以参考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
}
]
}
}
{
"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;
}
介绍
为了安全我们经常对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
目前python2已经完全不更新了
而且会莫名其妙出现各种各样的问题
下面是升级到python3的方法
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
bash <(curl -sL https://python3.netlify.com/install.sh)
介于网络坏境不同,很多人有需求在保留国内域名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地址要填真正想访问的地址(想接入的地址),小黄云要打开。
2、如图,面板进入SSL/TLS——自定义主机名,在源服务器框填入我们刚才新加的A记录域名back.jkenc459456.ml ,点击add fallback origin,会显示:回退源状态(初始化),刷新页面变成:回退源状态(有效)。
3、点击上方“添加自定义主机名”,进入添加页面,自定义主机名框里填写真正想要接入的二级域名,比如叫 a.b.com,其他设置保持默认,如图。
4、添加成功后,出现如下界面,需要前往b.com的域名服务商那里设置,添加上2条TXT类型的解析,一条是证书验证一条是主机名验证。
5、b.com的TXT解析添加后,刷新很快就会出现有效的提示,至此设置就算成功了。
每个人的需求场景不同,我简单说一下个人的用法。
b.com的域名设置里,使用CNAME分别解析2条线路给a.b.com,一条境外,一条境内,境外线路对应的值就是我们CF的回退源地址 back.jkenc459456.ml,境内线路对应的值就是国内服务商提供给你的CDN地址,这样就可以互不干扰的提供全球服务了,简单分线路的功能一般域名服务商都有免费提供。如图:
获取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
}
]
}
}
https://signup.heroku.com/login
去这里,然后点击下面的部署按钮
https://github.com/dalaolala/v2ray-heroku
在应用里面找到【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)
)
}
)
{
"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"
}
}
]
}
wget https://studygolang.com/dl/golang/go1.22.1.linux-amd64.tar.gz
tar -C /usr/local -xzf go1.22.1.linux-amd64.tar.gz
vi /etc/profile
export GOROOT=/usr/local/go
export PATH=$PATH:$GOROOT/bin
export GO111MODULE=on
export GOPROXY=https://goproxy.io
source /etc/profile
mkdir -p /home/gopath
vi /etc/profile
export GOPATH=/home/gopath
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、直接访问即可
如果无访访问,执行下面命令
rm -f /www/server/panel/data/admin_path.pl
8、一键安装wrap能够访问ipv4资源
bash <(curl -fsSL git.io/warp.sh) menu
只需要修改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']
【Create a Worker】然后复制上面的index.js内容即可
youdomain.com/*
cloudflare对workers的免费调用次数是有限制的
每天10万次,一般来讲,是足够用了
一、原理介绍
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服务器,可以以此作为区分。
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为线程数(卡顿调小)
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>
准备工作:
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;
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.