0%

SSH Port Forwarding

简介

SSH Port Forwarding 是一种通过安全的 SSH (Secure Shell)连接转发网络流量的技术,通常用于在不安全的网络环境中安全地传输数据, 访问受限资源或绕过防火墙规则。 在此技术中,会绑定一个本地端口,并且所有访问该端口的网络流量都将透明的被加密并被转发到远端主机,此时报文在 SSH Client 和 SSH Server 建立的加密通道中流动,因此也被称作 SSH Tunneling(隧道)。

本文介绍 PowerShell 中多线程相关内容。

Runspace

在 PowerShell 中,Runspace 是一个独立的执行环境,每个 Runspace 都有自己的变量、函数和状态,互相独立,各 Runspace 之间可以独立的运行 PowerShell 代码,相当于一个独立的会话或线程,允许在同一个进程中并行地运行多个 PowerShell 命令或脚本。

Windows 的 Job Objects(作业对象)允许将进程组作为一个单元进行管理。 作业对象是可访问的、安全的、可共享的对象,用于控制与其关联的进程的属性。 针对某个作业对象执行的操作会影响与该作业对象关联的所有进程。 包括如限制工作集大小和设置进程优先级,或终止与作业对象关联的所有进程等。

PowerShell 主要使用 C# 编写,其内部运行环境也是基于 .NET Framework,因此 PowerShell 与 .NET 交互十分简单。

本文给出了一个使用 PowerShell 脚本调用 C# 代码操作 Job Objects 的示例,该示例代码的功能是传入一个 Job Objects 的名称, 返回与该 Job Objects 关联的所有进程的 PID 列表。

摘要

本文展示在 bash 脚本中一些技巧和知识点。

ANSI-C Quoting

$'string' 形式的字符序列被视为一种特殊类型的单引号。该序列扩展为字符串,并按照 ANSI C 标准的规定替换字符串中的反斜杠转义字符。 简单说就是让 bash 知道这个字符串是转义字符,如 $'\n' 表示一个换行符,而 '\n' 仅是换行符的字面量表示。

摘要

本文提供一个检查 Linux 发行版本的 bash 脚本示例,一般用于程序对运行的操作系统版本有限制的情况下,使用引导脚本在程序启动前对操作的版本系统做检查。

检查脚本示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#!/usr/bin/env bash

set -eo pipefail

os_check() {
    # Prevent running on AIX and Darwin
    if [[ $(uname) != "Linux" ]]; then
        echo "unsupported OS $(uname), Linux ONLY"
        return 1
    fi

    declare -A distrib
    # support pattern matching, all Ubuntu distributions can pass check
    distrib["Ubuntu"]="*"
    # on RH 6.X 7.X, it's name is Red Hat Enterprise Linux Server
    # on RH 8.X 9.X, it's name is Red Hat Enterprise Linux
    distrib["Red Hat Enterprise Linux"]="6.* 7.* 8.* 9.*"
    distrib["Red Hat Enterprise Linux Server"]=${distrib["Red Hat Enterprise Linux"]}
    distrib["CentOS Linux"]="7 8"
    distrib["SLES"]="12.2 12.5"
    distrib["openEuler"]="22.03"
    distrib["Kylin Linux Advanced Server"]="V10"
    distrib["TencentOS Server"]="2.4 3.1"

    declare os_name os_version
    if [[ -f /etc/os-release ]]; then
        os_name=$(awk -F'"' '$1=="NAME="{print $2;exit}' /etc/os-release)
        os_version=$(awk -F'"' '$1=="VERSION_ID="{print $2;exit}' /etc/os-release)
    elif [[ -f /etc/redhat-release ]]; then
        # RH 6.x missing file /etc/os-release
        # file /etc/redhat-release example: Red Hat Enterprise Linux Server release 6.4 (Santiago)
        os_name="Red Hat Enterprise Linux Server"
        os_version=$(grep -oP 'release \K\S+' /etc/redhat-release)
    else
        echo "cannot get the OS distribution"
        return 1
    fi

    declare ver
    for ver in ${distrib["${os_name}"]}; do
        # shellcheck disable=SC2053
        if [[ ${os_version} == ${ver} ]]; then
            return 0
        fi
    done

    echo "unsupported OS distribution: ${os_name}, version: ${os_version}"
    return 1
}

os_check

# exec to your program here
# exec <bin file> [arguments]
echo "sleep 10 seconds ..."
sleep 10

常见Linux系统release文件整理

Ubuntu

Ubuntu 12.04

/etc/os-release
1
2
3
4
5
6
NAME="Ubuntu"
VERSION="12.04.5 LTS, Precise Pangolin"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu precise (12.04.5 LTS)"
VERSION_ID="12.04"
/etc/lsb-release
1
2
3
4
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=12.04
DISTRIB_CODENAME=precise
DISTRIB_DESCRIPTION="Ubuntu 12.04.5 LTS"

Ubuntu 14.04

/etc/os-release
1
2
3
4
5
6
7
8
9
NAME="Ubuntu"
VERSION="14.04.5 LTS, Trusty Tahr"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 14.04.5 LTS"
VERSION_ID="14.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
/etc/lsb-release
1
2
3
4
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=14.04
DISTRIB_CODENAME=trusty
DISTRIB_DESCRIPTION="Ubuntu 14.04.5 LTS"

Ubuntu 22.04

/etc/os-release
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
PRETTY_NAME="Ubuntu 22.04.3 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.3 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
/etc/lsb-release
1
2
3
4
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=22.04
DISTRIB_CODENAME=jammy
DISTRIB_DESCRIPTION="Ubuntu 22.04.3 LTS"

Red Hat

Red Hat 6.4

/etc/os-release

no such file

PowerShell 可以使用 Windows Global Event 来实现防止在同一时刻同一个脚本重复运行。

示例脚本

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
function Lock-Singleton
{
    $Locked = $false
    $Global:Mutex = New-Object System.Threading.Mutex($true, "Global\ChangeToYourUniqueEventNameHere", [ref]$Locked)
    if (-not $Locked)
    {
        $Global:Mutex.Close()
        Write-Host "another process is running now, exit"
        Exit 1
    }
}

Lock-Singleton

Write-Host "doing something here, sleep 10s"
Start-Sleep -Seconds 10

$Global:Mutex.Close()

Exit 0

防重也可以使用脚本名称和参数来查找该脚本是否正在运行,但此方案在脚本名称和参数唯一性(存在同名脚本)和一致性(变更了脚本名称)得不到保证, 可能存在误判的概率。

摘要

本文介绍了 SELinux 的标签、策略这两个核心基本概念和三种访问控制机制(TE、MLS、MCS)。

名词解释

  1. SELinux: 全称 Security Enhanced Linux,中文译作安全增强型 Linux。 基于最小化权限原则设计开发的 Linux 安全机制,下文将做详细介绍。
  2. DAC: 全称 Discretionary Access Control,中文译作自主访问控制。 用户对属于自己的资源有完全控制权限,如 UNIX 和 Windows 中的文件系统权限,其文件的所有者可以不受限的设置文件的访问权限,包括读、写和执行。
  3. MAC: 全称 Mandatory Access Control,中文译作强制访问控制。 在 MAC 中,系统管理员定义了资源和主体之间的访问规则,这些规则是强制性的,无法由主体自行更改。SELinux 就是一个典型的 MAC 实现。

SELinux 是什么

SELinux 是一个标签系统。每个进程、文件、目录,甚至网络端口和设备,都有一个标签,这些标签称作安全上下文 (Security Context)。 可以编写规则控制带某个标签的进程对带某个标签的的对象(如文件)的访问,这些控制规则称作 SELinux 策略。 Linux 内核强制执行这些规则,这种强制执行称作强制访问控制(MAC)。

摘要

介绍 bash 脚本 errexit 机制的例外情况和解决方案,如使用 if 调用函数时,errexit 机制在 if 上下文1中不会生效。

背景

在之前的 文章 中有介绍到 bash 脚本的 errexit 机制,讲到在 bash 脚本中开启 errexit 选项后 在遇到非零的返回状态码时,bash 脚本会停止执行并退出,同时也介绍了几种不会退出的特殊情况。

摘要

awk 是 Unix-like 系统上最强大的文本处理工具,其灵活的语法和丰富的功能使其可以优雅方便地处理各种文本任务。 本文系统性的介绍了AWK的语法和执行流程,并给出了实际使用场景的案例。适用于对 awk 不了解的读者。