分类目录归档:运维

作为运维人,必懂的知识,全在这里啦

Linux 编译安装 Nginx

引言

在生产环境中,Nginx 通常以源码编译的方式来安装,一则生产环境网络要求苛刻,二则可以自选模块,比如在 复用 443 端口时候,需要用到 stream_ssl_module 模块。

本文以 CentOS 7 和 Debian 11 操作系统为例,文中第四部分是如何新增模块,重新编译已经安装好的 Nginx 服务。

安装

安装依赖包

以下适用于 CentOS 7 | RadHat 7

yum install -y libtool autoconf cmake curl vim \
gcc gcc-c++ \
openssl openssl-devel \
pcre pcre-devel \
zlib zlib-devel \
libxml2 libxml2-devel \
libxslt libxslt-devel \
gd gd-devel \
GeoIP GeoIP-devel GeoIP-data \
gperftools 

以下适用于 Debian 11

apt-get install gcc build-essential manpages-dev \
libpcre3 libpcre3-dev libxslt-dev \
libgeoip-dev google-perftools \
libgoogle-perftools4 libgoogle-perftools-dev \
libtcmalloc-minimal4 libgdchart-gd2-noxpm \
libgdchart-gd2-noxpm-dev -y

下载 Nginx | openssl 包

curl -LO https://nginx.org/download/nginx-1.23.3.tar.gz
curl -LO https://ftp.openssl.org/source/old/1.1.1/openssl-1.1.1k.tar.gz

解压

tar -zxvf nginx-1.23.3.tar.gz -C /usr/local/src
tar -zxvf openssl-1.1.1k.tar.gz -C /usr/local/src

cd /usr/local/src/nginx-1.23.3

useradd www

生成侦测文件

./configure \
--prefix=/usr/local/nginx \
--user=www \
--group=www \
--with-poll_module \
--with-threads \
--with-file-aio \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_xslt_module \
--with-http_image_filter_module \
--with-http_geoip_module \
--with-http_sub_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_mp4_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_auth_request_module \
--with-http_random_index_module \
--with-http_secure_link_module \
--with-http_degradation_module \
--with-http_slice_module \
--with-http_stub_status_module \
--with-mail --with-stream \
--with-stream_ssl_module \
--with-stream_ssl_preread_module \
--with-stream_realip_module \
--with-stream_geoip_module \
--with-stream_ssl_preread_module \
--with-google_perftools_module \
--with-pcre \
--with-openssl=/usr/local/src/openssl-1.1.1k \
--with-openssl-opt=enable-weak-ssl-ciphers

编译并安装

make && make install

守护进程脚本

vim /etc/systemd/system/nginx.service
[Unit]
Description=nginx - high performance web server
Documentation=http://nginx.org/en/docs/
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target

[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
ExecReload=/bin/sh -c "/bin/kill -s HUP $(/bin/cat /usr/local/nginx/logs/nginx.pid)"
ExecStop=/bin/sh -c "/bin/kill -s TERM $(/bin/cat /usr/local/nginx/logs/nginx.pid)"

[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl start nginx.service

重新编译已存在的 nginx

下载 Nginx

解压

生成侦测文件

在这里添加你想要添加的模块,比如 –with-stream_ssl_module,根据需求来

编译这里千万不要 make install

make

备份并复制

# 备份原有的 nginx 可执行文件
mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.default.bak

# 复制全新编译的 nginx
cp /usr/local/src/nginx-1.20.2/objs/nginx /usr/local/nginx/sbin/nginx

重新启动 Nginx

systemctl restart nginx

搭建 v2ray 服務

一、Environment

Operating System: CentOS 7
Server Location: San Jose

二、Let’s Start

1. 安裝和更新 V2Ray (安裝執行檔和 .dat 資料檔)

# bash <(curl -L https://raw.githubusercontent.com/v2fly/fhs-install-v2ray/master/install-release.sh)

1.1 安裝最新發行的 geoip.dat 和 geosite.dat (只更新 .dat 資料檔)(首次安裝,無需執行)

# bash <(curl -L https://raw.githubusercontent.com/v2fly/fhs-install-v2ray/master/install-dat-release.sh)

1.2 移除 V2Ray

# bash <(curl -L https://raw.githubusercontent.com/v2fly/fhs-install-v2ray/master/install-release.sh) --remove

2. 配置文件 /usr/local/etc/v2ray/config.json

{
    "log": {
        "access": "/var/log/v2ray/access.log",
        "error": "/var/log/v2ray/error.log",
        "loglevel": "warning"
    },
    
    "inbounds": [
    {
        "port": 33689,
        "listen": "127.0.0.1",
        "protocol": "vmess",
        "settings": {
            "clients": [
            {
                "id": "89e2d792-1d03-46ec-9210-23c52d9d4a2f",
                "alterId": 0
            }
            ]
        },
        
        "sniffing": {
            "enabled": true, 
            "destOverride": ["http", "tls"]
        },
        
        "streamSettings": {
            "network": "ws",
            "wsSettings": {
                "path": "/wYof60qQ"
            }
        }
    }
    ],

    "outbounds": [
    {
        "tag": "direct",
        "protocol": "freedom",
        "settings": {}
    },
    
    {
        "tag": "blocked",
        "protocol": "blackhole",
        "settings": {}
    }
    
    ],
    
    "routing": {
        "strategy": "rules",
        "settings": {
            "domainStrategy": "AsIs",
            "rules": [
            {
                "type": "field",
                "ip": ["geoip:private"],
                "outboundTag": "blocked"
            }
            ]
        }
    }
}

3. 守護進程脚本 /etc/systemd/system/v2ray.service

[Unit]
Description=V2Ray Service
Documentation=https://www.v2fly.org/
After=network.target nss-lookup.target

[Service]
User=nobody
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
NoNewPrivileges=true
ExecStart=/usr/bin/env v2ray.vmess.aead.forced=false /usr/local/bin/v2ray -config /usr/local/etc/v2ray/config.json
Restart=on-failure
RestartPreventExitStatus=23

[Install]
WantedBy=multi-user.targe

4. 重載、啓動、添加開機自啓、查詢狀態

systemctl daemon-reload
systemctl start v2ray.service
systemctl enable v2ray.service
systemctl status v2ray.service

三、參考文章

  • https://github.com/v2fly/fhs-install-v2ray
  • https://github.com/v2fly/fhs-install-v2ray/wiki/Migrate-from-the-old-script-to-this
  • https://www.v2ray.com/


搭建 Trojan-Go 服务

一、简介

熟悉的筒子们可以直接跳过第一部分

Trojan-Go 使用 Go 实现的完整 Trojan 代理,与 Trojan 协议以及 Trojan 版本的配置文件格式兼容。安全,高效,轻巧,易用。

支持使用多路复用提升并发性能,使用路由模块实现国内直连。

支持 CDN 流量中转(基于 WebSocket over TLS/SSL)

支持使用 AEAD 对 Trojan 流量二次加密(基于Shadowsocks AEAD)。

支持可插拔的传输层插件,允许替换 TLS,使用其他加密隧道传输 Trojan 协议流量。

完整配置教程和配置介绍参见 Trojan-Go文档

Trojan-Go 官方发行包

下载 Trojan-Go 二进制包,以 CentOS 为例

二、安装环境

  • 服务器一台(本文以 CentOS 7 为例)
  • 域名一个(本文以 trojan-go.domain.com 为例)
  • 域名对应的 SSL 证书(如何获取 SSL 证书,请点击这里
  • Trojan-Go 官方发行包 (本文以 v0.10.6 为例)

三、开始吧

# 下载依赖包
yum install vim wget curl unzip -y

# 创建安装目录
mkdir -p /usr/local/trojan-go && cd /usr/local/trojan-go

# 下载二进制包
curl -LO https://github.com/p4gefau1t/trojan-go/releases/download/v0.10.6/trojan-go-linux-amd64.zip

# 解压安装包
unzip trojan-go-linux-amd64.zip

编辑 Trojan-go 服务端主配置文件
vim /usr/local/trojan-go/config.json

{
    "run_type": "server",
    "local_addr": "::",
    "local_port": 443,
    "remote_addr": "127.0.0.1",
    "remote_port": 80,
    "password": [
        "rfha9342@#30ds",
        "-adA5^s23ej",
        "sc8)-1e%ER.PscU"
    ],
    "ssl": {
        "cert": "/root/.acme.sh/trojan-go.domain.com/fullchain.cer",
        "key": "/root/.acme.sh/trojan-go.domain.com/trojan-go.domain.com.key",
        "sni": "trojan-go.domain.com",
        "alpn": [
            "http/1.1"
        ],
        "session_ticket": true,
        "reuse_session": true,
        "fallback_addr": "127.0.0.1",
        "fallback_port": 80
    },
    "tcp": {
        "no_delay": true,
        "keep_alive": true,
        "prefer_ipv4": false
    },
    "mux": {
        "enabled": false,
        "concurrency": 8,
        "idle_timeout": 60
    },
    "websocket": {
        "enabled": true,
        "path": "/dHs7P",
        "host": "trojan-go.domain.com"
    },
    "mysql": {
        "enabled": false,
        "server_addr": "localhost",
        "server_port": 3306,
        "database": "",
        "username": "",
        "password": "",
        "check_rate": 60
    }
}

守护进程脚本 /etc/systemd/system/trojan-go.service

[Unit]
Description=Trojan-Go - An unidentifiable mechanism that helps you bypass GFW
Documentation=https://p4gefau1t.github.io/trojan-go/
After=network.target nss-lookup.target

[Service]
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
NoNewPrivileges=true
ExecStart=/usr/local/trojan-go/trojan-go -config /usr/local/trojan-go/config.json
Restart=on-failure
RestartSec=10s
LimitNOFILE=infinity

[Install]
WantedBy=multi-user.target

重载脚本,并将脚本添加至开机启动

systemctl daemon-reload
systemctl start trojan-go.service
systemctl enable trojan-go.service
systemctl status trojan-go.service

Windows Server 跨机房大文件传输解决方案

以下是需求背景介绍,各位看官可直接忽略,直奔主题。

北京冬奥会系统保障期间,安全工程师对各应用程式进行病毒扫描,将上海机房行情落地程式 superman.exe 识别成 Trojan Horse 并对其进行隔离,导致当日行情实时数据丢失,毫不知情地运作了 3 个交易日,已经对历史 K 线造成了影响。
而历史数据通常是非常多且大,各股票市场数据加起来约 200G 以上,需要从广东机房的行情主站 copy 数据到上海机房,在没有专线的情况下如何解决呢?于是乎,鄙人想到了 openssh 方案。

一、Enviroment

Operating SystemPrivate IPPublic IPLocationMark
Windows Server 2008 R2172.50.10.220180.77.23.41广东拥有完整数据的服务器
Windows Server 2012 R215.28.131.110180.68.24.42上海丢失数据的服务器

二、Install Open-SSH

1.建议将 安裝包 放置 C:\Program Files\OpenSSH\
2.然后用 Administrator 权限打开 PowerShell,来到 C:\Program Files\OpenSSH\ 路径下,输入以下命令进行安装、启动

powershell -ExecutionPolicy Bypass -File .\install-sshd.ps1
net start sshd
net start ssh-agent

3. 配置环境变量(继续在 PowerShell 中执行)

$env:Path="$env:Path;C:\Program Files\OpenSSH\"

以上操作,两台服务器都需进行

三、Configure

1.修改 sshd default port (在上海 15.28.131.110 上进行)

# 用文本编辑器打开 C:\ProgramData\ssh\sshd_config
# 将 Port=22 修改成 Port=9527 # 这里的 9527 是互联网端口,需要放行策略

2. 重启 sshd 服务

net stop sshd
net start sshd

四、Sync Data

开始同步数据,在广东 172.50.10.220 上,用 administrator 权限打开 PowerShell, 执行以下命令

scp.exe -r -P 9527 D:\data administrator@180.68.24.42:D:\data

五、More

更多参考文章
http://woshub.com/connect-to-windows-via-ssh/

Ansible 学习笔记 (一): 部署管理 Windows Server 遇到的一些坑

一、Environment

Operating SystemIPRemark
CentOS 7.4 172.50.1.119 Ansible Manager
Windows Server 2008 R2 172.50.1.172 Ansible Client

二、Let’s Start

Windows Server

  • Ansible requires PowerShell version 3.0 and .NET Framework 4.0 or newer to function on older operating systems like Server 2008 and Windows 7【Windows Server 2012 就不需要升级了,2012 的PowerShell默认版本就是 4.0】,如果能访问互联网,可以通过官方脚本自动升级,否则下载离线包(.NET Framework 4.5 | PowerShell 4.0 )进行安装
  • 重启Windows Server之后,打开PowerShell,查看升级是否成功,如图1所示
  • 开启 winrm 服务 (以下命令都在 PowerShell 中进行)
# 1.查看powershell执行策略
get-executionpolicy

# 2.更改powershell执行策略为remotesigned【输入y确认】
set-executionpolicy remotesigned

# 3.配置winrm service并启动服务
winrm quickconfig

# 4.修改winrm配置,启用远程连接认证【这里是PowerShell的命令,如果用cmd的话,@前面的' 和 末尾的' 要去掉的】【如图2所示】
winrm set winrm/config/service/auth '@{Basic="true"}'
winrm set winrm/config/service '@{AllowUnencrypted="true"}'

# 5.查看winrm service启动监听状态【如果有应答,说明服务配置并启动成功了】【如图3所示】
winrm enumerate winrm/config/listener
  • 设置防火墙入站规则 (允许5985端口入站通过,略)

CentOS 7

重点:千万不要 yum 安装,选择 pip 安装,或者二进制包安装。否则,即便安装了 pywinrm 插件也无法管理 Windows Server。报图4错误。

# 1.从官网下载pip包到本地,官网链接:https://pypi.org/project/pip/#files
[root@localhost ~]# wget https://files.pythonhosted.org/packages/8e/76/66066b7bc71817238924c7e4b448abdb17eb0c92d645769c223f9ace478f/pip-20.0.2.tar.gz

# 2.解压
[root@localhost ~]# tar -zxvf pip-20.0.2.tar.gz -C /usr/local

# 3.安装
[root@localhost ~]# cd /usr/local/pip-20.0.2
[root@localhost pip-20.0.2]# python3 setup.py install
  • 安装 pywinrm 插件
[root@localhost ~]# pip install pywinrm

... ...
Successfully installed pywinrm-0.4.1
  • pip 安装 ansible
[root@localhost ~]# pip install ansible

三、Configure and Test

配置文件默认路径:/etc/ansible/hosts

  • 在此配置文件尾巴追加以下信息,ansible_ssh_user 是 Windows Server 的用户名,ansible_ssh_pass 是Windows Server 的密码
[windows]
172.50.1.172 ansible_ssh_user="Administrator" ansible_ssh_pass="Password" ansible_ssh_port=5985 ansible_connection="winrm" ansible_winrm_server_cert_validation=ignore
  • 验证

[root@localhost ~]# ansible windows -m win_ping 
172.50.1.172 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

四、说明

  • 升级PowerShell到4.0要先升级.Net Franmwork;
  • 开启 winrm 服务在 CMD 下、PowerShell 下语法是不一样的,本文是在 PowerShell 下进行的,有截图为证;
  • 一定要安装pywinrm插件,否则管理Windows Server的时候会报错”msg”: “winrm or requests is not installed: No module named winrm”
  • 如果安装了 pywinrm 还是报这个错,是因为 yum 安装的 ansible 无法调用 pip 安装的 pywinrm 插件,故而建议用 pip 安装 ansible 或者用源码包安装 ansible。【这个坑埋得比较深】【用yum安装ansible无法调用 pip 安装的 pywinrm 插件,不确定是不是必现,但在我工作的测试环境出现了】

CentOS 安装 python3

CentOS 安装 python3 是一篇基础环境架设的日志记录

一、安装记录

# 安装依赖包
sudo yum install gcc gcc-c++ cmake pcre pcre-devel \
autoconf libtool zlib zlib-devel bzip2 bzip2-devel \
ncurses ncurses-devel readline readline-devel \
openssl openssl-devel xz lzma xz-devel \
sqlite sqlite-devel tk tk-devel \
libffi libffi-devel openssl-static -y

# 1.从官网下载Python 3.10.5 - 06-Jun-2022 12:08 [stable version]
sudo curl -LO https://www.python.org/ftp/python/3.10.5/Python-3.10.5.tgz

# 2.解压至/usr/local
sudo tar -xvf Python-3.10.5.tgz -C /usr/local

# 3.生成Makefile
cd /usr/local/Python-3.10.5
sudo ./configure

# 4.编译解压
sudo make -j 8 && sudo make install

# 5.验证 python3 和 pip 安装成功
python3 --version
pip3 --version

二、特别说明

  • 在安装 python3 的时候,已经将 pip 功能安装好了
  • pip install 的时候,如果在中国,建议指定中国清华大学源,e.g
pip install example -i https://pypi.tuna.tsinghua.edu.cn/simple

MySQL/MariaDB主从、半同步复制原理

一、主从复制原理

当 MySQL 的 Master 节点的数据有更改的时候,Master 会主动通知 Slave,这时 Slave 开启一个 I/O thread 主动来 Master 获取二进制日志,向 Master 请求二进制日志中记录的语句;Master 将二进制日志中记录的语句发给 Slave,Slave 则将这些语句存到中继日志中,进而从中继日志中读取一句,执行一句,直到所有的语句被执行完。而经 SQL 语句从中继日志中读取出来,再一一执行的进程叫做 SQL thread;将这些语句执行完之后,从节点的数据就和主节点的数据相同了,这就是所谓的 MySQL/MariaDB 主从复制。

  • Master 节点必须开启二进制日志功能
  • Slave 节点必须开启中继日志功能
  • Slave 节点需关闭二进制日志功能(默认不配置即可)
  • Master 和 Slave 节点需要配置不同的 server-id
  • Slave 节点需连接到Master节点

二、半同步复制原理

默认情况下,MySQL 5.5/5.6/5.7 和 MariaDB 10.0/10.1 的复制功能都是异步的,异步复制的情况下可以提供最佳的性能。但是如果 Slave 节点没有接收到 Master 节点发送过来的 binlog 日志时,会造成主从节点的数据不一致,甚至在恢复时造成数据丢失。

为了解决异步复制的数据丢失的问题,MySQL 5.5 引入一种半同步复制模式,该模式可以让 Slave 节点接收完 Master 节点发送的 binlog 日志文件并写入自己的中继日志之后,给 Master 节点一个反馈,告诉 Master 已经接收完毕,这时主库线程才返回给当前 session 告知操作完成。当出现超时情况 ( 可配置 ) 时,Master 节点会暂时切换到异步复制模式,直到至少有一个设置为半同步复制模式的 Slave 节点收到信息为止。

半同步复制模式必须在 Master、Slave 节点同时启用,否则 Master 节点默认使用异步复制模式。

MySQL 的半同步是通过加载 Google 为 MySQL 提供的半同步插件 semisync_master.so 和 semisync_slave.so 来实现的。其中前者是 Master 上需要安装的插件,后者是 Slave 上需要安装的插件。
MySQL 的插件位置默认存放在 $basedir/lib/plugin

Redis Cluster + tomcat + mysql

背景

在架设国民认证服务的时候,国民认证厂家程式码是基于 Redis Cluster + tomcat + mysql 部署,因考虑到开发环境,我们要求快速部署、快速开发,所以,我考虑用 docker-compose 进行部署。

根据 Redis官网 的提示,为了让 Docker 与 Redis Cluster 兼容,需要使用 Docker 的 host 网路模式

环境

Docker version 19.03.8

docker-compose version 1.28.5

程式码如下:

version: "3.8"

services:
  redis-6371: # 服务名称
    image: redis # 创建容器时所需的镜像
    container_name: redis-6371 # 容器名称
    restart: always # 容器总是重新启动
    network_mode: "host" # host 网络模式
    volumes: # 数据卷,目录挂载
      - /data/docker-redis/redis-cluster/6371/conf/redis.conf:/etc/redis/redis.conf
      - /data/docker-redis/redis-cluster/6371/data:/data
      - /etc/localtime:/etc/localtime:ro
    command: redis-server /etc/redis/redis.conf # 覆盖容器启动后默认执行的命令

  redis-6372:
    image: redis
    container_name: redis-6372
    network_mode: "host"
    volumes:
      - /data/docker-redis/redis-cluster/6372/conf/redis.conf:/etc/redis/redis.conf
      - /data/docker-redis/redis-cluster/6372/data:/data
      - /etc/localtime:/etc/localtime:ro
    command: redis-server /etc/redis/redis.conf

  redis-6373:
    image: redis
    container_name: redis-6373
    network_mode: "host"
    volumes:
      - /data/docker-redis/redis-cluster/6373/conf/redis.conf:/etc/redis/redis.conf
      - /data/docker-redis/redis-cluster/6373/data:/data
      - /etc/localtime:/etc/localtime:ro
    command: redis-server /etc/redis/redis.conf

  redis-6374:
    image: redis
    container_name: redis-6374
    network_mode: "host"
    volumes:
      - /data/docker-redis/redis-cluster/6374/conf/redis.conf:/etc/redis/redis.conf
      - /data/docker-redis/redis-cluster/6374/data:/data
      - /etc/localtime:/etc/localtime:ro
    command: redis-server /etc/redis/redis.conf

  redis-6375:
    image: redis
    container_name: redis-6375
    network_mode: "host"
    volumes:
      - /data/docker-redis/redis-cluster/6375/conf/redis.conf:/etc/redis/redis.conf
      - /data/docker-redis/redis-cluster/6375/data:/data
      - /etc/localtime:/etc/localtime:ro
    command: redis-server /etc/redis/redis.conf

  redis-6376:
    image: redis
    container_name: redis-6376
    network_mode: "host"
    volumes:
      - /data/docker-redis/redis-cluster/6376/conf/redis.conf:/etc/redis/redis.conf
      - /data/docker-redis/redis-cluster/6376/data:/data
      - /etc/localtime:/etc/localtime:ro
    command: redis-server /etc/redis/redis.conf


  mysql:
    restart: always
    image: mysql:5.7.21
    container_name: FIDO_mysql

    ports:
      - 3306:3306

    environment:
      TZ: Asia/Shanghai
      MYSQL_ROOT_PASSWORD: Admin123

    volumes:
      - /data/FIDO/mysql/mysql.conf.d:/etc/mysql/mysql.conf.d
      - /data/FIDO/mysql/lib/mysql:/var/lib/mysql
      - /etc/localtime:/etc/localtime:ro
      - /data/FIDO/mysql/logs:/logs

  tomcat:
    restart: always
    image: tomcat:8.5
    container_name: FIDO_tomcat

    ports:
      - 8081:8080

    volumes:
      - /data/FIDO/tomcat/webapps:/usr/local/tomcat/webapps
      - /data/FIDO/tomcat/conf/context.xml:/usr/local/tomcat/conf/context.xml
      - /data/FIDO/tomcat/logs:/usr/local/tomcat/logs
      - /etc/localtime:/etc/localtime:ro
    links:
      - mysql:FIDO_mysql