审计Zabbix模板自动发现规则是否报错

审计Zabbix模板自动发现规则是否报错

话不多说直接上脚本,自用的话替换一下脚本里面的API地址以及zabbix的用户名和密码即可。

#!/usr/bin/env python
# encoding=utf-8

import datetime
import json
import time

import requests


def getToken(url, post_headers, url_user, url_password):
    post_data = {
        "jsonrpc": "2.0",
        "method": "user.login",
        "params": {
            "user": url_user,
            "password": url_password
        },
        "id": 1
    }
    ret = requests.post(url, data=json.dumps(post_data), headers=post_headers)
    return json.loads(ret.text).get("result")


def timestamp_to_string(timestamp):
    # 转换成localtime
    time_local = time.localtime(timestamp)
    # …
阅读更多
检查RabbitMQ队列是否堵塞的Python脚本

检查RabbitMQ队列是否堵塞的Python脚本

啥也不说了,上脚本之前先说一下有种做成zabbix自动发现的方案不是很合适,因为线上的集群动不动就几千个queue,这样生成的zabbix监控项太多,综合各方面考虑都不是很合适,下面的方案是把结果写到文件里面,然后配置个让zabbix agent定时去扫关键字的模板,具体怎么弄就不赘述了,直接上我们的Python脚本哦。

# -*- coding: utf-8 -*-
import re
import subprocess
list_vhost_cmd = "/sbin/rabbitmqctl list_vhosts |grep -v 'Listing vhosts'"
list_vhost_result = subprocess.check_output(list_vhost_cmd, shell=True).strip().split('\n')
no_exception_count = 0
with open('./results.txt', 'w') as f:
    for vhost in list_vhost_result:
        list_queue_cmd = "/sbin/rabbitmqctl list_queues -p {0} |grep -Ev 'Listing queues|Timeout:|name\tmessages'".format(vhost)
        try:
            list_queue_result = subprocess.check_output(list_queue_cmd, shell=True).strip().split('\n') …
阅读更多
解决VSCode本地启动Django项目访问首页报TemplateDoesNotExist

解决VSCode本地启动Django项目访问首页报TemplateDoesNotExist

背景

最近发现用VSCode启动一个django项目后访问首页会报TemplateDoesNotExist错误,表现如下:

但是用Pycharm启动的就不会报这个错,经过一番研究,原来是setting.py中的TEMPLATES设置没有和BASE_DIR join一下,不完善的会导致报错的配置如下:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': 'templates',
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
                'blog.context_processors.add_variable_to_context',
            ],
            'string_if_invalid': 'InvalidVariable'
        },
    },
]

若要修复上述错误,需要按照如下配置:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
                'blog.context_processors.add_variable_to_context', …
阅读更多
Bitwarden自建终极加固和最简单备份以及SMTP邮箱配置指南

Bitwarden自建终极加固和最简单备份以及SMTP邮箱配置指南

前言

如果你的bitwarden只托管了一些不重要的密码的话,可以看一下本站之前写的一篇博客(保姆级免Nginx反代配置带SSL证书Bitwarden服务端),基本也够安全的了,因为Bitwarden_RS/Vaultwarden(下文简称Bitwarden)底层采用的rocket tls最低支持版本是1.2,而不是1.0或1.1,具体看这里的官方文档

但是如果你的自建bitwarden托管了你的支付宝微信、银行卡、信用卡等全部身家,甚至几百个比特币的钱包的私钥,那前面提到的博客就不行了,我们必须再提高安全性,毕竟我们的服务暴露在了公网,一旦被不怀好意的人渗透了可就真的麻烦了。

终极加固实战

首先声明一下,一定一定一定要首先优先配置两步验证,这是最基础的安全措施,本文不再赘述~

另外本人遵循 "eat your own dog food"原则,本文全篇介绍的东西在本人自建的Bitwarden服务器上全部有应用到。

本人作为一名渣渣Linux运维小学生,着实才疏学浅,本文不能涵盖所有加固措施,遗漏的地方还望大家在评论区留言指出来,本人再补充进正文。

我们的加固涉及到了以下方面:

  • 禁止注册和邀请用户
  • 禁止显示密码提示
  • 基于Nginx实现禁止ip访问 (防止类似于shedon的邪恶搜索引擎搜索到,以及脚本小子扫描ip段)
  • 基于腾讯云控制台和Nginx讲解如何配置ECC算法的ssl证书,舍弃掉RSA算法的证书(ECC算法的破解难度要更高,比RSA算法要更上一个台阶),网上搜到的博客试了好几个都不行,我这里的一步到位
  • 让docker进程以非root用户运行,这里踩了一个坑,折腾了个把小时
  • 最后一步几乎将自建Bitwarden的安全性更上了一个台阶,那就是给后台的URL加上随机字符串,使得使用默认的后台地址无法访问
  • 最最后,由于我们的前端流量由Nginx承载,所以Nginx也要加固一下,下述共涉及 屏蔽Nginx的版本号减少攻击面、对Http请求方法进行限制、防止点击劫持、启用HSTS强制https访问、防止跨站攻击和摒弃不安全的ssl cipher且server端主动选择cipher共计6个方面。

基于某些考虑我们没有涉及的:

  • 配置fail2ban,自动封锁暴力破解者,这个有时候很容易在自己连续输入错几次密码后把自己给封了,即使你可以在手机上访问vps解封也比较繁琐,如果你按照本篇博客设置下来的话,配置fail2ban的意义也不是很大了。
  • docker的ssl挂载目录设置只读权限,因为我们采用了ECC算法的证书,而Bitwarden底层采用的rocket tls实现是不支持解析的,所以我们要移除掉相关设置,不用担心,本篇博客将会介绍如何用Nginx来实现解析ECC算法的证书
  • 舍弃掉你的主域名来作为服务入口,而是配置一个含有随机字符串的二级域名,这也是一个很不错的加固方式,本文也不再赘述

上述所有的加固措施在Bitwarden_rs/vaultwarden的官方wiki中都有提到,大神没必要再付费看我下面的描述了,不过如果你对上述加固措施不太熟悉的话,亦或者自己踩了很多坑搞不定的话,还是墙裂建议看看下面的描述的。

Tips:下述命令和Nginx指令比较零星,对技术不太熟悉的朋友很容易弄混淆,本人贴心的把docker的完整启动命令和关键指令含有注释的Nginx的完整配置分别贴了出来。

这一部分是付费阅读~

最简单备份指南

其实就是新建一个git私有仓库,然后写一个每天打包并自动push到远程仓库的脚本,再配置成定时任务就行了,国内vps推荐使用的gitee,国外的可以用github,

注意!!! 仓库一定要建成私有的哦 注意!!!

脚本如下:

cd /data && tar czvf bitwarden_backup_$(date '+%Y%m%d_%H%M').tgz bw-data/ && …
阅读更多
推送最近12小时内仍未解除的zabbix告警到企业微信群

推送最近12小时内仍未解除的zabbix告警到企业微信群

环境信息

  • zabbix 4.2.4
  • Python 3.6.8

说明

  • 本脚本在生产环境久经考验
  • 部分特殊场景可能会出现已经解除的告警依然会推送,原因未知
  • 自行替换脚本中的企业微信推送url,群id,zabbix api地址,zabbix用户名和密码

源码

#!/usr/bin/env python
# encoding=utf-8

import datetime
import json
import time

import requests


def send_msg_to_wework(chat_id, content):
    diag = {"chatid": chat_id,
            "msgtype": "markdown",
            "markdown": {
                "content": content}}

    headers = {"Content-Type": "application/json"}

    diag = json.dumps(diag)
    requests.post('http://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxx',
                  data=diag, headers=headers)


def getToken(url, post_headers, url_user, …
阅读更多
将turndown项目改造成CLI版本秒杀Python版的html2text

将turndown项目改造成CLI版本秒杀Python版的html2text

前言

先说说为啥nodejs版本的turndown项目在把html转换成markdown上会让我觉得秒杀掉python的老牌高star项目html2text,原因是我特别在意的一个功能就是代码高亮,很多python项目都不能在\`\`\`后自动加上语言类型,甚至html2text连加\`\`\`都做不到,好像可以加\<code\>\</code\>标签,不知道是不是等效于3个反引号。

然后我们再说回nodejs版本的turndown项目,这个项目牛逼之处就在于实例化时加上一个参数就可以实现自动识别代码高亮区域,加上\`\`\`和代码语言,但是呢这个牛逼的项目的作者在issue中明确表示对将项目改成cli版本的没任何兴趣,有需要的自行想办法。

实战

下面闲言少叙,我们进入实战环节。
首先,npm和node的安装和换源在这我就不赘述了,首先我们将turndown项目代码同步到本地,

git clone https://github.com/mixmark-io/turndown.git

然后我们用`vim`打开`package.json`,将第二行的`name`对应的值的后面随便加个字符串也就是变成别的名字,然后执行下面的命令安装`turndown`项目,

npm install turndown --save

最后将下面代码保存为一个`js`文件,如`md_helper.js`

// For Node
var TurndownService = require('turndown')

var turndownService = new TurndownService({ 'codeBlockStyle':'fenced' })
var myArgs = process.argv.slice(2)

var filename=myArgs[0]
const fs = require('fs')

try {
  const data = fs.readFileSync(filename, 'utf8')
  var markdown = turndownService.turndown(`${data}`) …
阅读更多
实战使用Pyenv离线安装Python3.7虚拟环境

实战使用Pyenv离线安装Python3.7虚拟环境

访问如下官方仓库:
https://github.com/pyenv/pyenv
将整个仓库以zip的形式下载到本地然后上传到服务器上的某个用户的家目录。

执行如下命令:

$ mkdir ~/.pyenv && cd ~/.pyenv && mv ~/pyenv-master.zip ./ && unzip pyenv-master.zip && mv pyenv-master/* ./ && rm -rf pyenv-master.zip pyenv-master/

然后执行如下命令写入环境变量:

echo -e 'if shopt -q login_shell; then' \
      '\n  export PYENV_ROOT="$HOME/.pyenv"' \
      '\n  export PATH="$PYENV_ROOT/bin:$PATH"' \
      '\n eval "$(pyenv init --path)"' \
      '\nfi' …
阅读更多
实战Grafana iFrame嵌入配置调教以及绘制各种图形技巧

实战Grafana iFrame嵌入配置调教以及绘制各种图形技巧

环境

  • CentOS 7
  • MySQL 5.7.30
  • Grafana 7.5.9

FAQ 1. 如何将Grafana Dashboard以iFrame形式嵌入第三方页面?

  • 开放匿名访问并限制权限, 在默认配置路径/etc/grafana/grafana.ini下的[auth.anonymous]修改为如下配置,
[auth.anonymous]
# enable anonymous access
enabled = true

# specify organization name that should be used for unauthenticated users
org_name = Main Org.

# specify role for unauthenticated users
org_role = Viewer
  • 在上述默认配置路径的[security]中允许使用嵌入
[security]
# set to true …
阅读更多