Vultr 监控机器使用流量并自动删除

我们在使用Vultr的过程中,经常会出现一不小心流量超出配额导致的天价流量费。

虽然Vultr官方有提供了流量预警之后自动关闭机器的功能,但毕竟关闭机器之后,每小时的机器费用还是需要支付的。像我这种喜欢开高配置机器的,每小时的使用费也是一笔不小的开支,因此抽空写了一个自动删除机器的脚本。

本文其实只是写了一个简单的shell脚本,基础功能还是由Vultr官方提供的vultr-cli来实现的。

1、从Vultr官方的github下载vultr-cli

https://github.com/vultr/vultr-cli/releases

2、解压下载的压缩包,把可执行文件复制到 /usr/bin 目录下

tar -xvf vultr-cli_*
mv vultr-cli /usr/bin/
rm vultr-cli_*

3、在Vultr后台开启API,并记录下API密钥,同时,将部署Shell的机器IP添加进允许列表(注意:如果机器支持IPv4、IPv6,记得同时添加IPv4和IPv6地址)

Vultr后台:https://my.vultr.com/settings/#settingsapi

4、新建vultr-cli.yaml,将API密钥保存进去(本文将文件保存在/home/vultr-cli.yaml)

api-key: [Vultr后台显示的API密钥]

5、新建vultr.sh,将以下内容粘贴进去(本文将文件保存在/home/vultr.sh)

#!/bin/bash
  
instanceIds=`vultr-cli instance list --config /home/vultr-cli.yaml|grep active|awk '{print $1}'`
for instanceId in $instanceIds; do
    allowBw=`vultr-cli instance get $instanceId --config /home/vultr-cli.yaml|grep BANDWIDTH|awk '{print $3}'`
    if [[ -z $allowBw ]]
    then
        continue
    fi
    inComingSum=`vultr-cli instance bandwidth $instanceId --config /home/vultr-cli.yaml|awk '{incoming+=$2} END {print incoming}'`
    if [[ -z $inComingSum ]]
    then
        continue
    fi
    outGoingSum=`vultr-cli instance bandwidth $instanceId --config /home/vultr-cli.yaml|awk '{outgoing+=$3} END {print outgoing}'`
    if [[ -z $outGoingSum ]]
    then
        continue
    fi
    if [ $inComingSum -gt $outGoingSum ]
    then
        let bandwidth=$inComingSum/1024/1024/1024
    else
        let bandwidth=$outGoingSum/1024/1024/1024
    fi
    let bwLeft=$allowBw-$bandwidth
    let bwSafeLeft=$allowBw*15/100
    echo $bwLeft
    echo $bwSafeLeft
    if [ $bwLeft -gt $bwSafeLeft ]
    then
        echo "bwLeft: $bwLeft, bwSafeLeft: $bwSafeLeft, less 85%!"
    else
        echo 'over 85%'
        vultr-cli instance delete $instanceId --config /home/vultr-cli.yaml
        echo "bwLeft: $bwLeft, bwSafeLeft: $bwSafeLeft, Deleted!"
    fi
done

6、执行vultr-cli,看下能否请求成功

vultr-cli instance list --config /home/vultr-cli.yaml

7、为vultr.sh添加执行权限

chmod +x /home/vultr.sh

8、将vultr.sh添加进定时任务

执行:crontab -e
在末尾添加一行:
* * * * * bash /home/vultr.sh
保存即可

8、撒花完结🎉~

结束语

现在,我们已经完成了脚本的部署。脚本将自动获取Vultr上面的机器并将使用流量超过85%的机器自动销毁。

需要注意的是,该脚本最好不要部署在Vultr的机器上面。(万一自己把自己删了怎么办?)

有的朋友会问,为什么要设置85%的阈值?这是因为Vultr的流量统计有延迟。我在实际使用过程中发现,在流量跑得快的情况下,设定85%删除机器,到实际流量更新后删除机器的时候,已经用了93%。

扶梯优化手册

· BBR

1、使用 uname -r 来确认内核是否大于4.9;

2、使用 lsmod | grep bbr 来确认是否有bbr模块,如有,跳到3;

没有发现bbr模块,执行:

sudo modprobe tcp_bbr
echo "tcp_bbr" | sudo tee --append /etc/modules-load.d/modules.conf

3、执行:

echo "net.core.default_qdisc=fq" | sudo tee --append /etc/sysctl.conf
echo "net.ipv4.tcp_congestion_control=bbr" | sudo tee --append /etc/sysctl.conf

4、保存生效:

sudo sysctl -p

· 系统优化

1、在 /etc/sysctl.conf 最后加入:

net.ipv4.tcp_fastopen = 3
net.ipv4.tcp_fastopen_blackhole_timeout_sec = 0
net.ipv4.ip_local_port_range = 1024 65535
net.ipv4.tcp_slow_start_after_idle = 0
fs.file-max = 1024000
net.ipv4.tcp_retries2 = 8
fs.inotify.max_user_instances = 8192
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_max_tw_buckets = 6000
net.ipv4.route.gc_timeout = 100
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_synack_retries = 1
net.core.somaxconn = 32768
net.core.netdev_max_backlog = 32768
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_max_orphans = 32768

2、保存生效:

sudo sysctl -p

3、在 /etc/security/limits.conf 最后加入:

* soft nofile 1024000
* soft nproc 1024000
* hard nofile 1024000
* hard nproc 1024000
root soft nofile 1024000
root soft nproc 1024000
root hard nofile 1024000
root hard nproc 1024000
nobody soft nofile 1024000
nobody soft nproc 1024000
nobody hard nofile 1024000
nobody hard nproc 1024000

4、重启生效

Ubuntu只允许Cloudflare连接

最近有一个比较特殊的需求,全站是通过Cloudflare去代理分发的,不允许除了Cloudflare之外的IP进行连接,用Ubuntu自带的iptables就可以实现。

1、安装 IPSet

apt update && apt install ipset -y

2、新建 /opt/cloudflare/cloudflare.sh

mkdir /opt/cloudflare/ && vim /opt/cloudflare/cloudflare.sh

3、写入cloudflare.sh,主要功能为获取Cloudflare的IPv4并写入ipset

#!/bin/bash
ipset create cloudflare hash:net maxelem 65536
wget -O /opt/cloudflare/cloudflareIP.txt https://www.cloudflare.com/ips-v4
ipset flush cloudflare
while read ip;do
 ipset add cloudflare $ip
done</opt/cloudflare/cloudflareIP.txt
ipset save cloudflare >/opt/cloudflare/cloudflareIP.conf

4、对 /opt/cloudflare/cloudflare.sh 授权并执行

chmod +x /opt/cloudflare/cloudflare.sh && /opt/cloudflare/cloudflare.sh

5、写入iptables规则

iptables -F
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -m set --match-set cloudflare src -p tcp -j ACCEPT
iptables -A INPUT -m set --match-set cloudflare src -p udp -j ACCEPT
iptables -A INPUT -p tcp -j DROP
iptables -A INPUT -p udp -j DROP
iptables -P INPUT DROP

数据来源:

Cloudflare官方IPv4IPv6

Ubuntu只允许中国IPv4进行访问

本文简单写几行命令,作为自己的备忘。实现效果为:22端口全网可通,其他端口仅允许中国IP访问。

1、安装 IPSet

apt update && apt install ipset -y

2、新建 /opt/chnroute/chnroute.sh

mkdir /opt/chnroute/ && vim /opt/chnroute/chnroute.sh

3、写入chnroute.sh,主要功能为获取中国IPv4并写入ipset

#!/bin/bash
ipset create chnroute hash:net maxelem 65536
wget --no-check-certificate -O- 'http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest'| awk -F\| '/CN\|ipv4/ { printf("%s/%d\n", $4, 32-log($5)/log(2)) }'>/opt/chnroute/chnroute.txt
ipset flush chnroute
while read ip;do
 ipset add chnroute $ip
done</opt/chnroute/chnroute.txt
ipset save chnroute >/opt/chnroute/chnroute.conf

4、对 /opt/chnroute/chnroute.sh 授权并执行

chmod +x /opt/chnroute/chnroute.sh && /opt/chnroute/chnroute.sh

5、写入iptables规则

iptables -F
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -m set --match-set chnroute src -p tcp -j ACCEPT
iptables -A INPUT -m set --match-set chnroute src -p udp -j ACCEPT
iptables -A INPUT -p tcp -j DROP
iptables -A INPUT -p udp -j DROP
iptables -P INPUT DROP

使用Nginx搭建WebDav作为简易共享空间

*本文仅作为备忘。

很多情况下,我们需要一个共享的存储空间,用来存储数据。基于软件的支持性调研结果,WebDav应该是最为适合的一种。

1、首先要安装Nginx

apt install nginx-full

2、配置域名和目录(下为配置文件示例)

server {
    listen 443 ssl http2;
    server_name test.com;

    ssl on;
    ssl_certificate /cert/test_ssl.pem;
    ssl_certificate_key /cert/test_ssl.key;
    root /webdata/test.com;
    if ( -d $request_filename ) {
      rewrite ^(.*[^/])$ $1/ break;
    }
    location / {
      charset         utf-8;
      autoindex       on;

      client_body_temp_path   /etc/nginx/client_temp;
      client_max_body_size    0;

      dav_methods PUT DELETE MKCOL COPY MOVE;
      dav_ext_methods PROPFIND OPTIONS;

      create_full_put_path    on;
      dav_access              group:rw all:r;

      auth_basic              "Access limited";
      auth_basic_user_file    /etc/nginx/user.passwd;
    }
}

3、创建鉴权文件:/etc/nginx/user.passwd

4、设置账户密码(下为示例)

echo "用户名:$(openssl passwd 密码)" >/etc/nginx/user.passwd

5、重启Nginx即可。

附录 · WebDav连接工具

Mac:(APP Store)推荐FE File Explorer

iPhone:(APP Store)推荐FE File Explorer

Windows:推荐RaiDrive(官网下载地址:https://www.raidrive.com/download

Android:没安卓设备,自己找

Nextcloud加密备份到腾讯云COS或阿里云OSS

写在前面

根据前文《从0开始安装Nextcloud》搭建了自己的Nextcloud网盘之后,有的小伙伴就会有疑问:如果硬盘损坏了怎么办?

本文提出的解决方案是将文件数据备份到云,这里衍生出来的另一个问题就是,既然备份到云,那么为什么不直接上传到云呢?其实是可以的,但安全性很难保证。

那备份到云的安全性又如何保证呢?这就是本文要解决的问题。

本文旨在解决两个问题:

1、放在本地,硬盘坏了怎么办?

2、放在云上,数据安全性怎么保障?

实现原理

1、Nextcloud有一个功能叫“服务器端加密”,开启后用户上传的文件都会被加密。

*注意:开启后新上传的才会被加密

2、将阿里云OSS或者腾讯云COS挂载到本地文件系统

3、将Nextcloud中加密的文件数据同步到挂载的远程目录

操作步骤

本文其实是通过将腾讯云COS或阿里云OSS挂载到本地文件系统之后进行管理的,具体的挂载步骤可参考《挂载阿里云OSS到本地当远程磁盘》和《挂载腾讯云COS到本地当远程磁盘》。

本文的内容是从上述文章完成后,即已经将阿里云OSS或腾讯云COS挂载到本地/files之后开始的。

1、开启Nextcloud的“服务器端加密”

在Nextcloud的 设置 -> 管理 -> 安全 ->服务器端加密 中开启。

2、启用加密模块

在Nextcloud的 应用 -> Default encryption module -> 启用

3、注销登陆重新登录,以初始化你的加密密钥

4、安装rsync

apt install rsync

5、同步data文件到/files(排除加密文件)

rsync -av --exclude "files_encryption" /webdata/nextcloud/data/ /files/

至此,文件已经成功同步到云上了,而因为我们没有上传密钥,因此实际上我们没有泄漏任何有效的资料。

*注意:是使用定时任务还是手动触发同步,需要各位看官自己去研究

注意事项

1、用户的私钥和解密用户文件所需的所有其他密钥保存在 data/<user>/files_encryption ,需要用户手动备份

2、私钥和解密存储在系统范围的外部存储中的文件所需的所有其他密钥保存在data/files_encryption,需要用户手动备份

3、*如果上述的密钥丢失,可能导致用户无法找回自己的文件

参考资料

1、Nextcloud Encryption configuration

2、rsync

挂载腾讯云COS到本地当远程磁盘

COSFS 工具支持将 COS 存储桶挂载到本地,像使用本地文件系统一样直接操作腾讯云对象存储中的对象

——腾讯云COSFS概述

写在前面

本文没有任何技术含量,仅仅就是记录一下操作步骤以便其他文章引用。

操作步骤

1、安装依赖

sudo apt-get install automake autotools-dev g++ git libcurl4-gnutls-dev libfuse-dev libssl-dev libxml2-dev make pkg-config fuse

2、获取 COSFS,保存在 /usr/cosfs

git clone https://github.com/tencentyun/cosfs /usr/cosfs

3、编译和安装(如果出现错误,可以到官方文档去找解决方案)

cd /usr/cosfs
./autogen.sh
./configure
make
sudo make install

4、创建配置文件 /etc/passwd-cosfs,此处需要去腾讯云 API密钥管理里面获取<SecretId> 和 <SecretKey>

echo <BucketName-APPID>:<SecretId>:<SecretKey> > /etc/passwd-cosfs

5、给予 /etc/passwd-cosfs 正确的权限

chmod 640 /etc/passwd-cosfs

6、进行挂载(<CosDomainName> 为存储桶对应的访问域名,形式为http://cos.<Region>.myqcloud.com)

cosfs <BucketName-APPID> <MountPoint> -ourl=<CosDomainName> -odbglevel=info

同样的,本文挂载到/files文件夹,至此,就挂载成功了。

cosfs mateor-cn-1256170000 /files -ourl=http://cos.ap-guangzhou.myqcloud.com -odbglevel=info

注意事项

1、编辑已上传文件会导致文件被重新上传

2、需要远程访问COS服务器,所以性能较差

3、重命名文件/文件夹可能会出错(若操作失败,可能会导致数据不一致)

4、不适合高并发读/写的场景

5、数据一致性由您自行维护(所以需要避免出现多个客户端写同一个文件的情况)

参考资料

1、腾讯云COSFS概述

挂载阿里云OSS到本地当远程磁盘

ossfs能让您在Linux系统中,将对象存储OSS的存储空间(Bucket)挂载到本地文件系统中,您能够像操作本地文件一样操作OSS的对象(Object),实现数据的共享。

——阿里云OSSFS概述

写在前面

本文没有任何技术含量,仅仅就是记录一下操作步骤以便其他文章引用。

操作步骤

1、阿里云OSS控制台创建一个Bucket,此处本文命名为mateor-cn-bucket,读者自行修改

2、本页面选择对应版本的软件下载地址,我是Ubuntu Server 18.04,因此我的下载地址是:

http://gosspublic.alicdn.com/ossfs/ossfs_1.80.6_ubuntu18.04_amd64.deb?spm=a2c4g.11186623.2.15.2ddc7358PWdRCh&file=ossfs_1.80.6_ubuntu18.04_amd64.deb

3、下载软件

wget 'http://gosspublic.alicdn.com/ossfs/ossfs_1.80.6_ubuntu18.04_amd64.deb?spm=a2c4g.11186623.2.15.2ddc7358PWdRCh&file=ossfs_1.80.6_ubuntu18.04_amd64.deb'

4、安装OSSFS(依次执行)

sudo apt-get update
sudo apt-get install gdebi-core
sudo gdebi ossfs*.deb

5、创建/etc/passwd-ossfs文件,格式参照下述命令

echo my-bucket:my-access-key-id:my-access-key-secret > /etc/passwd-ossfs

此处我执行的就是:

echo mateor-cn-bucket:我的AccessKeyId:我的AccessKeySecret > /etc/passwd-ossfs

*注意:其中my-access-key-idmy-access-key-secret需要到阿里云用户信息管理去生成。

6、修改/etc/passwd-ossfs文件的权限

chmod 640 /etc/passwd-ossfs

7、挂载Bucket到指定目录

ossfs my-bucket my-mount-point -ourl=my-oss-endpoint

比如我将mateor-cn-bucket挂载到本地的/files,且我的OSS对象存储EndPoint地址为:oss-cn-shenzhen.aliyuncs.com,那么我执行的就是:

ossfs mateor-cn-bucket /files -ourl=http://oss-cn-shenzhen.aliyuncs.com

*注意:这里如果出现错误提示,如:

ossfs: unable to access MOUNTPOINT /files: No such file or directory

是因为要挂载的文件夹不存在,需要先创建再挂载

mkdir /files

至此,OSS就已经成功挂载到本地了,下图中256T的就是挂载的OSS。

如果不再需要挂载,那么可以执行进行卸载:

fusermount -u /files

注意事项

1、编辑已上传文件会导致文件被重新上传

2、需要远程访问OSS服务器,所以性能较差

3、重命名文件/文件夹可能会出错(若操作失败,可能会导致数据不一致)

4、不适合高并发读/写的场景

5、数据一致性由您自行维护(所以需要避免出现多个客户端写同一个文件的情况)

参考资料

1、阿里云OSSFS概述