core dump又叫核心转储, 当程序运行过程中发生异常, 程序异常退出时, 由操作系统把程序当前的内存状况存储在一个core文件中, 叫core dump. (linux中如果内存越界会收到SIGSEGV信号,然后就会core dump)

一、 配置基于 systemd 的 core dump

该模式下的核心转储文件默认保存在 /var/lib/systemd/coredump, 默认保存三天
该核心转储功能由journal配合产生, 因此控制转储文件的保存目录以及时间较难, 如需自定义, 推荐使用传统方式配置核心转储。

编辑文件 /etc/systemd/system.conf ,添加/修改以下行:

DumpCore=yes
DefaultLimitCORE=infinity

编辑文件 /etc/systemd/coredump.conf , 添加/修改一下行:

[Coredump]
Storage=external # 将核心转储存储在文件系统中
Compress=yes # 是否压缩转储文件
ProcessSizeMax=2G # 大小限制 (0 表示不限制)
ExternalSizeMax=2G
JournalSizeMax=767M
MaxUse=5G
KeepFree=1G

编辑文件 /etc/sysctl.conf 添加/修改以下行:

kernel.core_pattern=|/usr/lib/systemd/systemd-coredump %P %u %g %s %t %c %h

应用上述配置并生效: systemctl daemon-reexec && sysctl -p

二、 core dump 实例分析

使用一个简单的 C 程序验证 core dump

#include <stdio.h>

int main() {
int *p = NULL;
*p = 1; // This will cause a segmentation fault
return 0;
}

编译并执行 gcc test.c && ./a.out

图片

2.2 基于systemd的 coredump 处理

  • 列出所有核心转储
    coredumpctl list
    图片

    • PID: 崩溃进程的 PID。
    • SIG: 导致崩溃的信号编号(如 11 表示 SIGSEGV)
    • COREFILE: 表示核心转储是否存在(present 或 missing)
  • 查看特定核心转储的详细信息
    coredumpctl info <PID>
    图片

  • 导出核心转储文件
    coredumpctl dump <PID>
    图片

  • 分析核心转储
    coredumpctl gdb <PID>
    图片

三、 传统方式配置 coredump

与基于 coredumpctl 方式不同, 该方式下, 转储文件会直接生成

3.1 开启coredump

  • 启用核心转储
    ulimit -c unlimited

    • 编辑 /etc/security/limits.conf 文件,添加或修改以下行:
      * soft core unlimited
      * hard core unlimited
      该配置允许用户生成无限大小的core文件

3.2 自定义转储文件的目录及大小

  • 编辑文件 /etc/sysctl.conf 添加/修改以下行:

    kernel.core_pattern = /var/coredumps/core-%e-%s-%u-%g-%p-%t
    • %e: 可执行文件名
    • %s: 导致 core dump 的信号号
    • %u: 进程的实际用户 ID
    • %g: 进程的实际组 ID
    • %p: 进程 ID
    • %t: core dump 的时间(UNIX 时间戳)
  • 创建转储目录
    mkdir /var/coredumps
    chmod 777 /var/coredumps

  • 应用并生效
    sysctl -p

  • 测试
    可以看见, 该方式下, 转储文件直接生成
    图片

一、 逻辑备份/恢复

基于MySQL自带的mysqldumpmysqlpump进行逻辑备份和恢复

优点 缺点
可以跨平台和MySQL版本 备份速度慢, 占用较大的cpu和I/O

1.1 逻辑备份

#!/bin/bash

MYSQLDUMP=/data/mysql/bin/mysqldump
MYSQL=/data/mysql/bin/mysql
DBNAME=(db1 db2 db3 db4) ## 输入要备份的数据库,空格隔开。
DATE=$(date -d "now" +%Y-%m-%d)
BACKUP_ROOT=/data/mysql_logical_bak
BACKUP_DIR=${BACKUP_ROOT}/${DATE}
LOGFILE=${BACKUP_DIR}/backup.log
HOST=localhost
PORT=3306
USER=root
PASSWD=$password
EXPIRE_DAYS=30

function fun_mkdir(){
mkdir -p ${BACKUP_DIR}
}

function fun_lock_tables(){
echo "Locking all tables..."
$MYSQL -h${HOST} -P${PORT} -u${USER} -p${PASSWD} -e "FLUSH TABLES WITH READ LOCK;"
}

function fun_unlock_tables(){
echo "Unlocking all tables..."
$MYSQL -h${HOST} -P${PORT} -u${USER} -p${PASSWD} -e "UNLOCK TABLES;"
}

function fun_backup(){
for DB in "${DBNAME[@]}"
do
echo "Backing up $DB..."
$MYSQLDUMP -h${HOST} -P${PORT} -u${USER} -p${PASSWD} \
--compress --databases --routines --quick --set-gtid-purged=OFF \
${DB} | gzip > ${BACKUP_DIR}/${DB}.sql.gz
if [[ $? == 0 ]]; then
echo "$(date -d "now" "+%Y-%m-%d %H:%M:%S") - Database: ${DB} backup successful." >> $LOGFILE
else
echo "$(date -d "now" "+%Y-%m-%d %H:%M:%S") - Database: ${DB} backup failed!" >> $LOGFILE
fi
done
}

function fun_cleanup(){
echo "Cleaning up old backups..."
find ${BACKUP_ROOT} -type d -mtime +${EXPIRE_DAYS} -exec rm -rf {} +
}

source ~/.bash_profile && source /etc/profile

if [ -z $BACKUP_ROOT ]; then
echo "BACKUP_ROOT is not set" && exit 1
fi

fun_mkdir
fun_lock_tables
fun_backup
fun_unlock_tables
fun_cleanup

echo "Backup process completed."

# Uncomment the following line to enable remote backup syncing
###rsync -avrz --delete $BACKUP_ROOT/ root@$REMOTEHOST:$REMOTELOCATION

1.2 逻辑恢复

gunzip < ${BACKUP_DIR}/${DB_NAME}.sql.gz | mysql -h${HOST} -P${PORT} -u${USER} -p${PASSWD}

二、 物理备份/恢复

XtraBackup 是由 Percona 提供的开源备份工具,主要用于 MySQLMariaDBPercona Server 数据库的备份。它可以为 InnoDBXtraDB 存储引擎提供热备份功能,这意味着可以在数据库继续运行、读写数据的情况下进行备份,而不会影响应用程序的正常使用。

2.0 安装 XtraBackup

yum install epel-release -y && yum install percona-xtrabackup -y

2.1 物理备份

#!/bin/bash

DATE=$(date -d "now" +%Y-%m-%d)
CONFIG_FILE="/etc/my.cnf"
BACKUP_ROOT="/data/mysql_physical_bak"
BACKUP_DIR="${BACKUP_ROOT}/${DATE}"
LOGFILE="${BACKUP_DIR}/backup.log"
SOCKET="/usr/local/mysql/mysql.sock"
USER="root"
PASSWD="$password"
PORT=3306
EXPIRE_DAYS=30

function fun_mkdir() {
mkdir -p "${BACKUP_DIR}"
}

function fun_backup() {
innobackupex --defaults-file="${CONFIG_FILE}" \
--user="${USER}" \
--password="${PASSWD}" \
--port="${PORT}" \
--socket="${SOCKET}" \
--compress \
--parallel=4 \
"${BACKUP_DIR}" > "${LOGFILE}" 2>&1
}

function fun_cleanup_old_backups() {
find "${BACKUP_ROOT}" -mindepth 1 -maxdepth 1 -type d -mtime "+${EXPIRE_DAYS}" -exec rm -rf {} \;
}

source ~/.bash_profile && source /etc/profile

if [ -z "${BACKUP_ROOT}" ]; then
echo "BACKUP_ROOT is not set" && exit 1
fi

fun_mkdir
fun_backup
fun_cleanup_old_backups

echo "Backup process completed. Check ${LOGFILE} for details."

# Uncomment the following line to enable remote backup syncing
# rsync -avrz --delete "${BACKUP_ROOT}/" "root@${REMOTE_HOST}:${REMOTE_LOCATION}"

2.2 物理恢复

假设场景: 从主库的物理备份中创建一个从库, 并开启主从复制。
假设物理备份的位置: /data/mysql/backup-physical
主从数据库的数据目录: /data/mysql/data

  • 解压备份
    这个步骤会在每个压缩文件旁边创建一个解压后的版本
    innobackupex --decompress /data/mysql/backup-physical/ > decompress.log 2>&1
    图

  • 恢复到MySQL数据目录
    默认会根据 /etc/my.cnf 恢复, 也可以使用 --datadir="your_data_path"
    --copy-back :复制数据到目标目录下,当前备份数据不删除
    --move-back :移动数据到目标目录下,当前数据会删除(适合存储空间不大的情况)
    xtrabackup --copy-back --target-dir=/data/mysql/backup-physical/

    从库启动之前, 如果主库发生变化, 需要将主库备份时间节点之后的bin-log文件复制到从库的数据目录

  • 修改MySQL数据目录的权限
    chown -R mysql:mysql /data/mysql/data

  • 启动MySQL
    systemctl start mysqld

  • 配置从库

    mysql> 
    mysql> change master to \
    -> master_host='16.167.13.137',
    -> master_user='repl',
    -> master_password='$yourpassword',
    -> master_auto_position=1;
    Query OK, 0 rows affected, 2 warnings (0.04 sec)

    mysql>
    mysql> start slave;
    Query OK, 0 rows affected (0.00 sec)

2.3 常见问题

主从同步的时候提示: Could not execute Update rows event on table xxxxxx: can't find record in xxxxxx
原因: 从库启动之前主库数据发生变动
解决: 发生数据变动期间的 bin-log 文件复制到从库的数据目录

三、 增量备份

查看某个用户拥有某个数据库的权限

注意这里的 127.0.0.1localhost不一样

mysql> show grants for 'root'@'127.0.0.1';
+-----------------------------------------------------------------------------+
| Grants for root@127.0.0.1 |
+-----------------------------------------------------------------------------+
| GRANT SELECT, INSERT, UPDATE ON *.* TO 'root'@'127.0.0.1' WITH GRANT OPTION |
+-----------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql>
mysql> show grants for 'root'@'localhost';
+---------------------------------------------------------------------+
| Grants for root@localhost |
+---------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION |
| GRANT PROXY ON ''@'' TO 'root'@'localhost' WITH GRANT OPTION |
+---------------------------------------------------------------------+
2 rows in set (0.00 sec)

一般来说,nfs 用于Linux之间的文件共享, 跨平台使用 samba

零、 环境说明

CLIENT: 192.168.1.201 (CentOS7.9)
SERVER: 192.168.12.73 (Winserver2016)
文档涉及的ip地址以及目录路径请根据实际情况填写,切勿完全复制粘贴。

一、 NFS服务端部署

winserver2016为例,使用powershell部署NFS,其他版本未测试。

1.1 安装 NFS

Import-Module ServerManager
Add-WindowsFeature FS-NFS-Service
Import-Module NFS

图片1

1.2 创建共享目录

New-NfsShare -Name nfs1 -Path C:\Users\Administrator\Desktop\share

1.3 防火墙配置

New-NetFirewallRule -DisplayName "Allow NFS" -Direction Inbound -Protocol TCP -LocalPort 2049 -Action Allow
New-NetFirewallRule -DisplayName "Allow NFS" -Direction Inbound -Protocol UDP -LocalPort 2049 -Action Allow

1.4 目录权限配置

图片1

1.5 挂载

注意: 需要指定版本
mount -t nfs -o vers=4.1 192.168.12.73:/nfs1 /mnt/nfs1

1.6 开机挂载

echo 192.168.1.100:/nfs1 /mnt/nfs1 nfs defaults,vers=4.1 0 0 >> /etc/fstab

一、 准备工作

1.1 修改源: /etc/apt/source.list

deb https://mirror.nju.edu.cn/proxmox/debian/pve bookworm pve-no-subscription
deb https://mirror.nju.edu.cn/debian/ bookworm main contrib non-free
deb http://download.proxmox.com/debian/pve bookworm pve-no-subscription

1.2 修改源: /etc/apt/source.list.d/pve-no-subscription.list

deb https://mirrors.ustc.edu.cn/proxmox/debian/pve bookworm pve-no-subscription

1.3 注释企业版订阅:

/etc/apt/source.list.d/pve-enterprise.list

1.4 更新

apt update && apt dist-upgrade

二、 相关报错

2.1 pve-apt-hook: not found

/bin/sh: 1: /usr/share/proxmox-ve/pve-apt-hook: not found
E: Sub-process /usr/share/proxmox-ve/pve-apt-hook returned an error code (127)
E: Failure running script /usr/share/proxmox-ve/pve-apt-hook

解决:

mkdir -p /usr/share/proxmox-ve
touch /usr/share/proxmox-ve/pve-apt-hook
chmod +x /usr/share/proxmox-ve/pve-apt-hook

2.2 ceph-common Depends

ceph-common : Depends: librbd1 (= 16.2.15-pve1) but 17.2.7-pve2~bpo11+1 is to be installed
Depends: python3-cephfs (= 16.2.15-pve1) but it is not going to be installed
Depends: python3-ceph-argparse (= 16.2.15-pve1) but 17.2.7-pve2~bpo11+1 is to be installed
Depends: python3-ceph-common (= 16.2.15-pve1) but 17.2.7-pve2~bpo11+1 is to be installed
Depends: python3-rados (= 16.2.15-pve1) but it is not going to be installed
Depends: python3-rbd (= 16.2.15-pve1) but it is not going to be installed
Depends: python3-rgw (= 16.2.15-pve1) but it is not going to be installed

原因: 存在不通版本的pve源,或者没有取消企业版pve的源,导致update的时候部分软件包安装报错, 降级相关软件包重新安装 proxmox-ve即可

前言

假设 Server A 上有一个ipv4的站点: a.ipv4.domain.com
不修改 A 的配置,添加一台支持ipv4和ipv6双栈的公网服务器B;
在 Server B 上通过nginx配置ipv6反向代理ipv4, 实现 ipv6用户访问ipv4资源;

Feature Server A Server B
address ipv4: 100.1.1.1
site: your.domain.com
ipv4: 100.1.1.2
ipv6: 2408:4005:30a:ce00:98b:29f6:6606:xxxx

域名配置

your.domain.com A 记录解析到 100.1.1.1
ipv4.your.domain.com A 记录解析到 100.1.1.1
your.domain.com AAAA 记录解析到 2408:4005:30a:ce00:98b:29f6:6606:xxxx

nginx 配置

这里nginx 只监听ipv6的端口
在 Server B部署 nginx

server {
listen [::]:80;
server_name localhost;

... # 其他配置

location / {
proxy_pass http://ipv4.your.domain.com;
}

先说结论:

  • firewalld无法控制来自本地的流量
  • iptables 可以控制来自本地的流量
  • iptables 默认对ipv4生效,ip6tables对ipv6生效
  • telnet 命令默认会将localhost被解析成::1
  • nmap 会按照/etc/hostslocalhost解析成127.0.0.1
  • ping 在不通的操作系统下localhost的解析效果也不一样, centos中解析为127.0.0.1 debian12 中是 ::1

环境介绍

Feature Server A Server B
OS: CentOS 7.9 Debian 12
ARCH: KVM x86-64 KVM x86-64
IP: 192.168.1.201 192.168.1.28
Docker Remote Port: 2376 2376
Firewalld Version: v0.6.3 v1.3.3

两台服务器默认 iptables为空, firewalld 为空;
默认情况下, iptables 允许放行,firewalld 拒绝;

两台服务器的docker端口均默认监听在tcp6

端口测试脚本:

#!/bin/bash

# Define the port to test
PORT=2376

# Define the addresses to test
ADDRESSES=("localhost" "127.0.0.1" "$(hostname -I | awk '{print $1}')" "::1")

# Function to test telnet connection
test_telnet() {
local address=$1
echo -n "Testing $address:$PORT... "
if timeout 2 telnet $address $PORT 2>/dev/null | grep -q "Connected"; then
echo "Connected"
else
echo "Connection failed"
fi
}
# Loop through the addresses and test each one
for address in "${ADDRESSES[@]}"; do
test_telnet $address
done

测试一

1.1 CentOS:

图片1

1.2 Debian:

图片2

图片3
图片4

结论: firewalld 并不能控制来自本地的流量,即使public的接口里添加了 lo

测试二

两台服务器都添加 iptables 规则后再继续执行脚本测试

iptables -I INPUT -p tcp --dport 2376 -j DROP
图片4
图片4

脚本省略了命令行的输出, 用命令测试一下 telnet localhost 2376
发现两台服务器解析localhost的时候默认解析成 ::1

结论:
iptables 可以阻止来自本地的流量,包括环回接口lo
iptables 默认只处理 ipv4 的流量, ipv6的流量使用 ip6tables
localhost默认会解析成::1

前言

实际应用场景中发现centos7中的firewalld对docker容器监听的端口有时候生效, 有时候不生效, 基于此情况深入研究docker的网络模式

一、 Bridge

bridge 是最常用的默认网络配置选项之一。它为容器创建一个虚拟化的网络环境,通过虚拟网络桥接(Bridge)连接容器,并提供网络隔离和互通功能。bridge 网络模式非常适合单机环境中的容器网络配置。

特点:

  • 1.1 默认网桥:

    docker0 是 Docker 默认创建的虚拟网络桥接器。所有没有显式指定网络模式的容器都会连接到这个默认网桥网络。

  • 1.2 网络隔离:

    连接到 docker0 网桥网络的容器可以相互通信,同时与其他未连接到 docker0 网络的容器以及宿主机隔离

  • 1.3 自动ip分配:

    Docker 会自动为连接到 docker0 网络的容器分配 IP 地址,这些地址通常在 172.17.0.0/16 子网范围内(具体范围可以根据 Docker 配置变化)。

  • 1.4 NAT和端口映射:

    通过 docker0 网桥,Docker 使用网络地址转换(NAT)使容器能够访问外部网络。外部网络无法直接访问容器,除非通过端口映射显式允许。

二、 Host

该网络模式是一种特殊的网络配置选项,它允许容器使用宿主机的网络堆栈。这意味着在 host 网络模式下,容器不会获得独立的网络命名空间,而是与宿主机共享网络配置。

三、 Overlay

Docker 集群中创建跨主机容器通信的网络模式。它允许不同主机上的容器像在同一网络中一样相互通信,适用于使用 Docker Swarm 或 Kubernetes 等编排工具的多主机部署场景。

四、 Ipvlan

IPvlan 模式是一种高级的 Docker 网络模式,它允许您对容器的 IPv4 和 IPv6 地址进行更精细的控制。 它还可以处理第 2 层和第 3 层 VLAN 标记和路由。

五、 Macvlan

Macvlan网络模式是一种高级网络配置选项,它允许用户为每个容器分配唯一的 MAC 地址,使容器能够直接与宿主机的物理网络进行通信。macvlan 模式提供了高性能和良好的隔离性,适用于需要直接访问物理网络的场景。

一、 重要说明:

kexec 实现的是一种快速重启,它可以避免传统的 BIOS/UEFI 启动过程,但实际上系统内的所有进程确实会终止并重新启动。因此,尽管使用 kexec 可以跳过硬件初始化的过程,系统层面的重启依然会发生

    1. 加载新内核kexec -l 命令会将新内核加载到内存中,同时准备好初始内存盘(initrd)等启动所需的数据。
    1. 停止当前进程并执行新内核:当执行 kexec -e 时,当前正在运行的系统会立即终止所有用户态进程,清理掉旧内核占用的资源,然后切换到新内核,重新启动整个系统。
    • 这个过程跳过了 BIOS/UEFI 等硬件初始化步骤(如自检、硬盘探测等),直接由 CPU 开始执行新加载的内核。
    • 但是,所有进程仍然会终止并重新启动,因为新内核需要一个干净的状态。换句话说,从操作系统的角度来看,所有进程都会被关闭,只不过跳过了硬件层面的重启。

二、 安装新内核

2.1 添加公钥

rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org

2.2 添加源


### Name: ELRepo.org Community Enterprise Linux Repository for el7
### URL: https://elrepo.org/

[elrepo]
name=ELRepo.org Community Enterprise Linux Repository - el7
baseurl=https://mirrors.nju.edu.cn/elrepo/archive/elrepo/el7/$basearch/
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-elrepo.org
protect=0

[elrepo-testing]
name=ELRepo.org Community Enterprise Linux Testing Repository - el7
baseurl=http://elrepo.org/linux/testing/el7/$basearch/
enabled=0
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-elrepo.org
protect=0

[elrepo-kernel]
name=ELRepo.org Community Enterprise Linux Kernel Repository - el7
baseurl=https://mirrors.nju.edu.cn/elrepo/archive/kernel/el7/$basearch/
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-elrepo.org
protect=0

[elrepo-extras]
name=ELRepo.org Community Enterprise Linux Extras Repository - el7
baseurl=https://mirrors.nju.edu.cn/elrepo/archive/extras/el7/$basearch/
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-elrepo.org
protect=0

2.3 安装TL版本

yum install -y kernel-lt kernel-lt-devel

2.4 查看已安装内核

awk -F\' '$1=="menuentry " {print $2}' /etc/grub2.cfg

三、 切换内核

3.1 更新 GRUB 配置

grub2-mkconfig -o /boot/grub2/grub.cfg

3.2 确保安装了 kexec

yum install kexec-tools

3.3 找到新安装的内核路径

ls -ahl /boot/vmlinuz-*
图
ls -ahl /boot/initramfs-*
图

3.4 加载新内核

kexec -l /boot/vmlinuz-5.4.278-1.el7.elrepo.x86_64 --initrd=/boot/initramfs-5.4.278-1.el7.elrepo.x86_64.img --reuse-cmdline

3.5 切换内核

kexec -e

3.6 检查系统

图

一、 Docker Server 开启 remote api

注意:
方法一和方法二冲突, 只需要配置一个即可

1.1 方法一、 编辑 docker.service

ExecStart=/usr/bin/dockerd -H fd:// \
-H tcp://0.0.0.0:2375 \
-H unix://var/run/docker.sock \
--containerd=/run/containerd/containerd.sock

1.2 方法二、 编辑 /etc/docker/daemon.json

{
"hosts": ["tcp://0.0.0.0:2375","unix:///var/run/docker.sock"]
}

1.3 验证 remote api 是否开启

docker -H tcp://0.0.0.0:2375 version

二、 开启TLS

注意:
docker server 主机上执行

2.1 生成 CA 私钥

openssl genrsa -aes256 -out ca-key.pem 4096

2.2 生成 CA 证书

openssl req -new -x509 -days 365 -sha256 \
-key ca-key.pem \
-out ca.pem \
-subj "/C=CN/ST=Zhejiang/L=Hangzhou/O=dockerapi/OU=dockerspi/CN=$HOST"

2.3 生成 Server 私钥

openssl genrsa -out server-key.pem 4096

2.4 生成 Server 证书请求

openssl req -subj "/CN=$HOST" -sha256 -new -key server-key.pem -out server.csr

echo subjectAltName = DNS:$HOST,IP:192.168.1.201,IP:127.0.0.1 >> extfile.cnf
echo extendedKeyUsage = serverAuth >> extfile.cnf

2.5 使用 CA证书 签署证书

openssl x509 -req -days 365 -sha256 -in server.csr \
-CA ca.pem -CAkey ca-key.pem \
-CAcreateserial -out server-cert.pem \
-extfile extfile.cnf

2.6 修改 service 文件

ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2376 \
--tlsverify \
--tlscacert=/etc/docker/ssl/ca.pem \ # ca 证书
--tlscert=/etc/docker/ssl/server-cert.pem\ # server 证书
--tlskey=/etc/docker/ssl/server-key.pem # server 私钥

systemctl daemon-reload
systemctl restart docker

三、 客户端配置

注意:
docker client 主机上执行

3.1 生成 client 私钥

openssl genrsa -out client-key.pem 4096

3.2 生成 client 证书请求

openssl req -subj '/CN=client' -new -key client-key.pem -out client.csr

3.3 使用 CA 签署证书

echo extendedKeyUsage = clientAuth > extfile-client.cnf

openssl x509 -req -days 365 -sha256 \
-in client.csr \
-CA ca.pem \
-CAkey ca-key.pem \
-CAcreateserial -out client-cert.pem \
-extfile extfile-client.cnf

3.4 访问验证

docker --tlsverify  \
--tlscacert=ca.pem \
--tlscert=client-cert.pem \
--tlskey=client-key.pem \
-H=192.168.1.201:2376 version

3.5 配置全局docker变量

mkdir -pv ~/.docker
cp ./ca.pem ~/.docker/ca.pem
cp ./client-cert.pem ~/.docker/cert.pem
cp ./client-key.pem ~/.docker/key.pem
export DOCKER_HOST=tcp://$HOST:2376 DOCKER_TLS_VERIFY=1

配置完成之后可以直接使用 docker ps 查看

四、 相关问题

4.1 cannot validate certificate for xx.xx.xx.xx because it doesn’t contain any IP SANs

解决: 证书生成的过程中要指定ip, 参照docker

零、 名词解释

本机: Windows 11 (192.168.1.25)
服务器: CentOS 7 (192.168.1.201)

SSH客户端: 192.168.1.25 OpenSSH_for_Windows_8.6p1, LibreSSL 3.4.3
SSH服务端: 192.168.1.201 OpenSSH_7.4p1, OpenSSL 1.0.2k-fips

一、 远程转发&本地转发

两个SSH客户端之间建立一个安全的通道
本地计算机上的端口转发到远程计算机上,或者反向转发,将远程计算机上的端口转发到本地计算机上

1.1 本地转发实例:

应用场景:

  • 绕过防火墙限制, 访问服务器任意资源.

Windows上执行:
ssh -L 8080:localhost:4000 user@remote_server

windows上的8080–>远程服务器的4000

1.2 远程转发实例:

192.168.1.201上执行:

ssh -R 8888:localhost:8006 [email protected]

访问192.168.1.201:8888 –> 192.168.1.200:8006

二、 动态转发(Dynamic Port Forwarding)

ssh -D $port -N user@host

SSH服务端和客户端建立加密连接
SSH客户端还会建立一个socks5代理, 所有从socks出去的流量,都通过这个加密连接转发。

应用场景:

  • 匿名访问互联网
  • 绕过防火墙限制

实例:
Windows上通过 ssh -D 5000 -N [email protected]与服务端建立ssh加密隧道
通过本地socks5的5000端口,实现Windows访问服务器192.168.1.201的任意资源.
图
图