跳转至

2023

Intel SDM(Software Developer's Manual)

Introduction

This set consists of

volume Descriptions pages(size)
volume 1 Basic Architecture 500 pages(3MB)
volume 2 (combined 2A, 2B, 2C, and 2D) full instruction set reference 2522 pages(10.8MB)
volume 3 (combined 3A, 3B, 3C, and 3D) system programming guide 1534 pages(8.5MB)
volume 4 MODEL-SPECIFIC REGISTERS (MSRS) 520 pages

volume3: Memory management(paging), protection, task management, interrupt and exception handling, multi-processor support, thermal and power management features, debugging, performance monitoring, system management mode, virtual machine extensions (VMX) instructions, Intel® Virtualization Technology (Intel® VT), and Intel® Software Guard Extensions (Intel® SGX).

AMD64 Architecture Programmer's Manual (3336 pages)

more graph and easier to read.

需要进一步的研究学习

暂无

遇到的问题

暂无

开题缘由、总结、反思、吐槽~~

参考文献

上面回答部分来自ChatGPT-3.5,没有进行正确性的交叉校验。

https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html

Make

导言

虽然大型项目会使用cmake,手写makefile的情况比较少,但是基本语法还是要熟悉的。

LinuxCommand: system info

时间

CST

CST 也可以指 中国标准时间(China Standard Time),UTC+8。这是中国的法定时区,没有夏令时调整。

date +"%Y-%m-%d %H:%M:%S %Z %:z

  • %Z 显示时区缩写(如 CST)。
  • %:z 显示时区偏移量(如 +08:00、-06:00)。

修改时间

timedatectl 是一个管理日期和时间的工具,可以用来永久设置系统时间和时区。

sudo timedatectl set-time "2024-10-26 19:12:19"

修改时区

如果发现时区也不正确,可以用下面的命令设置时区:

sudo timedatectl set-timezone "Asia/Shanghai"

例如,将时区设置为中国标准时间 (CST, UTC+8),时区名称需要使用 timedatectl list-timezones 查看可用的时区列表。

硬盘/挂载空间

df -h .

各个文件夹空间

deep为1

du -h -d .

进程查看与kill

# thi
ps aux | grep 1499321
ps -auxf | grep -nB 10 -E 'python[3]?|PID'
kill -9 

ps aux linux command whill show no zero cpu usage when the process is sleeping beacuse of its snapshots mechanism

apt-get problems

dpkg: 处理归档 /var/cache/apt/archives/bat_0.12.1-1build1_arm64.deb (--unpack)时出错:
 正试图覆盖 /usr/.crates2.json,它同时被包含于软件包 ripgrep 11.0.2-1build1
dpkg-deb: 错误: 粘贴 子进程被信号(断开的管道) 终止了
在处理时有错误发生:
 /var/cache/apt/archives/bat_0.12.1-1build1_arm64.deb
E: Sub-process /usr/bin/dpkg returned an error code (1)
sudo apt-get purge -h
# jsonfile conflict purge - Remove packages and config files

tree

deep size

tree -L DepthSIze Folder_Path

so文件分析

#分析symbols 
nm -gDC intel64/gcc4.8/*
  • -g:显示全局符号表。
  • -D:显示动态符号表。
  • -C:将 C++ 符号名还原成源代码中的名称。

综合来看,使用 nm -gDC <filename> 命令可以查看一个二进制可执行文件或者共享库中的全局符号表和动态符号表,并将包含其中的 C++ 符号名还原成源代码中的名称。

shaojiemike@snode6 ~/github/gem5  [10:49:56]
> nm /usr/local/lib/libprotobuf.a |c++filt|grep google::protobuf::MessageFactory::InternalRegisterGeneratedFile
                 U google::protobuf::MessageFactory::InternalRegisterGeneratedFile(char const*, void (*)(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&))
0000000000000e00 T google::protobuf::MessageFactory::InternalRegisterGeneratedFile(char const*, void (*)(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&))

#分析子so
ldd .so

参考文献

Linux CMD

简介

  • 常用的linux命令行指令。
  • 包括少量实验数据的初步处理(bash脚本)和简单可视化(excel/echart)

Cpu Time

Situation

It is all started with two confusing situation.

  • I found out using ps aux | grep -v process_name, the process is in Sl+ state. But the cpu usage is not zero.
  • watch "ps aux |grep 3496617" always show the same cpu usage percentage, which is very confusing beacause htop always show up-down value. and pidstat -p 3516617 show cpu% less than 100%.

Git Standardization

workflow

内容模板

隐藏文件夹 .github , 里面放两个文件:

ISSUE_TEMPLATE.md

PULL_REQUEST_TEMPLATE.md

分支模型

Git Flow 分支模型

仓库有两个基础分支:

dev(默认分支)
master(用于发布)

通过pull request来合并新的代码:

协作者的代码通过pr合并到dev
dev通过pr合并到master

注意点:

merge 到 dev,使用squash merge
merge 到 master,使用普通的merge
永远不向master直接commit代码

GitHub Flow 分支模型

只有一个长期分支 master ,而且 master 分支上的代码,永远是可发布状态,

CI(Continuous Integration)集成

netlify

to do

github action

github自带的,貌似比Travis CI好用

ctest 怎么写

自动化生成TOC 目录

可以使用 toc-generator

  1. 在README里配置插入TOC的位置
<!-- START doctoc -->
<!-- END doctoc -->
  1. 配置GitHub Action, 需要在仓库的Settings > Actions > General里的Workflow permissions开启Read and write permissions
name: Generate TOC
on:
push:
    branches:
    - main

jobs:
toc:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - uses: technote-space/toc-generator@v4
        with:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

travis ci

Travis CI 提供的是持续集成服务(Continuous Integration,简称 CI)。它绑定 Github 上面的项目,只要有新的代码,就会自动抓取。然后,提供一个运行环境,执行测试,完成构建,还能部署到服务器。

持续集成的好处在于,每次代码的小幅变更,就能看到运行结果,从而不断累积小的变更,而不是在开发周期结束时,一下子合并一大块代码。

  1. 使用准备
  2. 登录 https://app.travis-ci.com/ ,绑定github,选择监听仓库.
  3. 项目里面有可运行的代码,项目还包含构建或测试脚本
  4. .travis.yml
  5. 在项目根目录下新建 .travis.yml 文件。参考官方文档编写 https://docs.travis-ci.com/user/languages/cpp/
  6. 运行流程
  7. install 阶段:安装依赖
  8. script 阶段:运行脚本
  9. 可选部分
before_install:install 阶段之前执行
before_script:script 阶段之前执行
after_failure:script 阶段失败时执行
after_success:script 阶段成功时执行
before_deploy:deploy 步骤之前执行
after_deploy:deploy 步骤之后执行
after_script:script 阶段之后执行
  1. 运行状态
passed:运行成功,所有步骤的退出码都是0
canceled:用户取消执行
errored:before_install、install、before_script有非零退出码,运行会立即停止
failed :script有非零状态码 ,会继续运行
  1. 可选加密环境变量

git commit 规范

Angular规范

<type>(<scope>): <subject>

type 必须

name description 实例
feat: 新功能(feature)。 打印函数 feat: Add print function for enhanced runtime information
fix/to: 修复bug,可以是QA发现的BUG,也可以是研发自己发现的BUG。
fix: 产生diff并自动修复此问题。适合于一次提交直接修复问题
to: 只产生diff不自动修复此问题。适合于多次提交。最终修复问题提交时使用fix
docs: 文档(documentation)。
style: 格式(不影响代码运行的变动)。
refactor: 重构(即不是新增功能,也不是修改bug的代码变动)。
perf: 优化相关,比如提升性能、体验。
test: 增加测试。
chore: 构建过程或辅助工具的变动。
revert: 回滚到上一个版本。
merge: 代码合并。
sync: 同步主线或分支的Bug。

规范化commit message

格式为:

<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
  1. 对于Revert: If the commit reverts a previous commit, it should begin with revert:, followed by the header of the reverted commit. In the body it should say: This reverts commit <hash>., where the hash is the SHA of the commit being reverted.
  2. type的类型有:

  3. feat: A new feature

  4. fix: A bug fix
  5. docs: Documentation only changes
  6. style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)空白、格式、缺少分号等
  7. refactor:(重构) A code change that neither fixes a bug nor adds a feature
  8. perf: A code change that improves performance
  9. test: Adding missing or correcting existing tests
  10. chore: (琐事)Changes to the build process or auxiliary tools(辅助工具) and libraries such as documentation generation

  11. scope: commit 改变的位置,如果是多处写*

  12. subject: 简明的描述:
  13. 使用祈使句,现在时态
  14. 不要.结尾
  15. 第一个字母不要大写
  16. body: 包括改变的动机,并将其与以前的行为进行对比。
  17. footer: Breaking Changes或者reference GitHub issues that this commit closes. Breaking Changes should start with the wordBREAKING CHANGE: with a space or two newlines. The rest of the commit message is then used for this.

自动生成Release Notes

规范化commit

插件 vscode插件git-commit-plugin

命令行 husky + commitlint

工具

  1. Standard Version
  2. 实现自动化版本控制,自动创建changelog, 创建 git tags
  3. 安装
npm cache clean --force #npm指令清除npm缓存
# 删除node_module包
npm install -g npm # npm 更新到最新
npm install -g n
n latest # node 更新
   Note: the node command changed location and the old location may be remembered in your current shell.
            old : /usr/bin/node
            new : /usr/local/bin/node
   To reset the command location hash either start a new shell, or execute PATH=$PATH"
PATH=/usr/local/bin/:$PATH
npm install -D standard-version
  1. 编写package.json
"scripts": {
   "release": "standard-version"
}
  1. CHANGELOG.md 记录内容的配置

    1. 创建.versionrc
    {
    "types": [
       {"type": "chore", "section":"Others", "hidden": false},
       {"type": "revert", "section":"Reverts", "hidden": false},
       {"type": "feat", "section": "Features", "hidden": false},
       {"type": "fix", "section": "Bug Fixes", "hidden": false},
       {"type": "improvement", "section": "Feature Improvements", "hidden": false},
       {"type": "docs", "section":"Docs", "hidden": false},
       {"type": "style", "section":"Styling", "hidden": false},
       {"type": "refactor", "section":"Code Refactoring", "hidden": false},
       {"type": "perf", "section":"Performance Improvements", "hidden": false},
       {"type": "test", "section":"Tests", "hidden": false},
       {"type": "build", "section":"Build System", "hidden": false},
       {"type": "ci", "section":"CI", "hidden":false}
    ]
    }
    
  2. 使用Standard Version

// 初次发布版本
npm run release --first-release
npm run release #(自动更新版本号,自动更新 CHANGELOG.md, 自动创建 git tag)
git push --follow-tags origin master
  1. 寄
  2. Commitizen for contributors
  3. Linux下commit规范辅助,用来选择(没vscode的时候用)
  4. 用 git-cz 来提交文件
  5. https://www.jianshu.com/p/acfdd4ca0104
  6. Visual Studio Code Commitizen Support vscode的插件
  7. conventional-changelog/commitlint 阻止不规范的提交

github-release-notes

github-release-notes,以下简称 gren ,是用来一键向 github 发布 release notes 的工具。 https://zhuanlan.zhihu.com/p/99499246

https://blog.csdn.net/weixin_39586683/article/details/110643111

release 语义化版本 semver

版本格式:主版本号.次版本号.修订号,版本号递增规则如下:

主版本号:当你做了不兼容的 API 修改, 次版本号:当你做了向下兼容的功能性新增, 修订号:当你做了向下兼容的问题修正。 先行版本号及版本编译信息可以加到“主版本号.次版本号.修订号”的后面,作为延伸。

Git auto-release requirements

  1. github Actions / travis-ci
  2. 自动化测试
  3. Commitizen / Visual Studio Code Commitizen Support
  4. 规范commit message
  5. standard-version
  6. 更新 package 版本并打 tag
  7. github-release-notes
  8. 生成 release-log

需要进一步的研究学习

写个github模板

  1. 明确文件结构
  2. src/include/build/Doc/Debug/test/example
  3. 清晰的README
  4. Intro/Install&Run/Features/Bugs/Acknowledge
  5. 图片和标签
    1. https://shields.io/category/build
  6. Release的自动发布
  7. 规范commit
  8. 其他自动化的轮子持续整合 (Continuous Integration, CI)
  9. travis ci
  10. github action
    1. ctest 怎么写?
  11. cmake.yml
  12. .github/workflow
    1. https://github.com/iBug/AWS-Lambda-webhook-py/tree/master/.github/workflows
    2. https://github.com/Kirrito-k423/github-stats
  13. 文档生成
    1. doxygen
    2. Doxygen主要解决说明书问题,可以在我们写代码的时候讲注释转化为说明书,Graphviz主要是用于图形展示
    3. 有项目,文件,函数三部分的书写要求 https://www.cnblogs.com/silencehuan/p/11169084.html
  14. Codecov
    1. 代码覆盖率,执行部分占比。因为未执行部分可能是错的
  15. projects/ bug fixs
  16. 设置为 template repository
  17. 查看 https://app.travis-ci.com/github/Kirrito-k423/githubTemplate

plus

将网站变成带名字的md格式参考文献的插件

Boost 设置

set(Boost_USE_STATIC_LIBS ON)

set(Boost_DEBUG ON)

Boost_INCLUDE_DIR: 含有boost头文件的目录 Boost_LIBRARYDIR: 偏好的含有boost库的库目录

https://stackoverflow.com/questions/3897839/how-to-link-c-program-with-boost-using-cmake

Boost Install

http://c.biancheng.net/view/7772.html cache?

cmake boost install path

https://cloud.tencent.com/developer/ask/107360

设置boost-root 查看安装位置

Travis-CI Install

Travis-CI 依赖软件包每次都要重新安装吗

apt-get install in a GitHub Actions workflow

https://stackoverflow.com/questions/57982945/how-to-apt-get-install-in-a-github-actions-workflow

Actions may have no Boost, where

ctest

Ctest add build/bin to test

Ctest https://www.cnblogs.com/hustcpp/p/12922998.html

https://blog.csdn.net/zcteo/article/details/117527823?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EOPENSEARCH%7Edefault-15.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EOPENSEARCH%7Edefault-15.no_search_link

遇到的问题

暂无

开题缘由、总结、反思、吐槽~~

还是ipcc的github组织的太烂了,需要学习一下

参考文献

https://zhuanlan.zhihu.com/p/67620599

http://www.ruanyifeng.com/blog/2017/12/travis_ci_tutorial.html

https://github.com/levy9527/blog/issues/1

Linux Executable file: Structure & Running 2

可执行文件的运行

要运行可执行目标文件 prog,我们可以在 Linux shell 的命令行中输入它的名字: linux> ./prog 因为 prog 不是一个内置的 shell 命令,所以 shell 会认为 prog 是一个可执行目标文件。

进程的启动

  • Linux进程的启动是通过父进程复制一个子进程,子进程通过execve系统调用启动加载器。
  • 加载器(loader)删除子进程已有的虚拟存储段,
  • 通过将虚拟地址空间中的页映射到可执行文件的页大小组块,
  • 并创建一组新的代码、数据、堆、栈段,
  • 同时新的堆和栈被初始化为零。
  • 新的代码和数据段被初始化为可执行文件的内容,
  • 最后将CUP指令寄存器设置成可执行文件入口,启动运行。

执行完上述操作后,其实可执行文件的真正指令和数据都没有别装入内存中。操作系统只是通过可执行文件头部的信息建立起可执行文件和进程虚拟内存之间的映射关系而已。

memory map

除了一些头部信息,在加载过程中没有任何从磁盘到内存的数据复制。直到 CPU 引用一个被映射的虚拟页时才会进行复制,此时,操作系统利用它的页面调度机制自动将页面从磁盘传送到内存。

比如,现在程序的入口地址为 0x08048000 ,刚好是代码段的起始地址。当CPU打算执行这个地址的指令时,发现页面 0x8048000 ~ 0x08049000 (一个页面一般是4K)是个空页面,于是它就认为是个页错误。此时操作系统根据虚拟地址空间与可执行文件间的映射关系找到页面在可执行文件中的偏移,然后在物理内存中分配一个物理页面,并在虚拟地址页面与物理页面间建立映射,最后把EXE文件中页面拷贝到内存的物理页面,进程重新开始执行。该过程如下图所示:

接下来,加载器跳转到程序的入口点,也就是 _start函数的地址。这个函数是在系统目标文件 ctrl.o 中定义的,对所有的 C 程序都是一样的。_start 函数调用系统启动函数 __libc_start_main,该函数定义在 libc.so 中。它初始化执行环境,调用用户层的 main 函数,处理 main 函数的返回值,并且在需要的时候把控制返回给内核。

fork 和 execve 函数的差异

  • fork 函数在新的子进程中运行相同的程序,新的子进程是父进程的一个复制品。
  • execve 函数在当前进程的上下文中加载并运行一个新的程序。
  • 它会覆盖当前进程的地址空间,但并没有创建一个新进程。
  • 新的程序仍然有相同的 PID,并且继承了调用 execve 函数时已打开的所有文件描述符。

程序运行途中修改exe程序

  • 由于操作系统使用页表和虚拟内存机制来实现按需加载。按需加载意味着只有在程序执行到需要访问某个代码段时,才会将该代码段从可执行文件加载到内存中。
  • 那么如果我在程序运行的途中重新编译程序,修改了代码段,那么程序会怎么样呢?
  • Chatgpt:运行中的程序尝试执行新的代码时,会发生未定义的行为,因为操作系统不会自动将新的代码加载到正在运行的进程的内存中。
  • 一个页表4KB,一个程序的代码段可能有如下100KB甚至几十MB,不可能全部加载。
# shaojiemike @ snode6 in ~/github/sniper_PIMProf/PIMProf/gapbs on git:dev o [15:15:29]
$ size /usr/lib/llvm-10/bin/llvm-mca
   text    data     bss     dec     hex filename
 144530    6056    8089  158675   26bd3 /usr/lib/llvm-10/bin/llvm-mca

# shaojiemike @ snode6 in ~/github/sniper_PIMProf/PIMProf/gapbs on git:dev o [15:18:14]
$ l /usr/lib/llvm-10/bin/llvm-mca
-rwxr-xr-x 1 root root 153K Apr 20  2020 /usr/lib/llvm-10/bin/llvm-mca

程序运行途中修改python代码

  • 虽然修改python代码类似修改C代码,按理来说不会影响程序进行。但是python是逐行解释执行的,很难让人不思考会不会影响正在运行中的程序。
  • 答案是不会,原因有二:
  • python代码在运行时,会被编译成字节码,然后再执行字节码。修改python代码后,其对应的字节码会在下一次运行程序时,Python解释器对比文件时间戳时更新。
  • Python解释器在运行时,会将所需的文件提前加载到内存里

GDB调试修改

Memalloc

2

Buddy 内存分配

是一种用于管理计算机内存的算法,旨在有效地分配和释放内存块,以防止碎片化并提高内存的使用效率。这种算法通常用于操作系统中,以管理系统内核和进程的内存分配。

Buddy 内存分配算法的基本思想是将物理内存划分为大小相等的块,每个块大小都是 2 的幂次方。每个块可以分配给一个正在运行的进程或内核。当内存被分配出去后,它可以被分割成更小的块,或者合并成更大的块,以适应不同大小的内存需求。

算法的名称 "Buddy" 来自于分配的块之间的关系,其中一个块被称为 "buddy",它是另一个块的大小相等的邻居。这种关系使得在释放内存时,可以尝试将相邻的空闲块合并成更大的块,从而减少内存碎片。

Buddy 内存分配算法的工作流程大致如下:

  1. 初始时,整个可用内存被视为一个大块,大小是 2 的幂次方。

  2. 当一个进程请求内存分配时,算法会搜索可用的块,找到大小合适的块来满足请求。如果找到的块比所需的稍大,它可以被分割成两个相等大小的 "buddy" 块,其中一个分配给请求的进程。

  3. 当一个进程释放内存时,该块会与其 "buddy" 块合并,形成一个更大的块。然后,这个更大的块可以与其它相邻的块继续合并,直到达到较大的块。

Buddy 内存分配算法在一些操作系统中用于管理内核和进程的物理内存,尤其在嵌入式系统和实时操作系统中,以提高内存使用效率和避免碎片化问题。

ucore(Micro-kernel Operating System for Education)

是一个用于教育目的的微内核操作系统

linux遇到问题

我们可window写程序占满16G内存

但是linux,用了3GB就会seg fault

猜想是不是有单进程内存限制 https://www.imooc.com/wenda/detail/570992

而且malloc alloc的空间在堆区,我们可以明显的发现这个空间是被栈区包住的,有限的。windows是如何解决这个问题的呢? 1. 首先这个包住是虚拟地址,通过页表映射到的物理地址是分开的 2. 根据第一点,可以实现高地址动态向上移动

动态数据区一般就是“堆栈”。“栈 (stack)”和“堆(heap)”是两种不同的动态数据区,栈是一种线性结构,堆是一种链式结构。进程的每个线程都有私有的“栈”,所以每个线程虽然 代码一样,但本地变量的数据都是互不干扰。一个堆栈可以通过“基地址”和“栈顶”地址来描述。全局变量和静态变量分配在静态数据区,本地变量分配在动态数 据区,即堆栈中。程序通过堆栈的基地址和偏移量来访问本地变量。

当进程初始化时,系统会自动为进程创建一个默认堆,这个堆默认所占内存的大小为1M。堆对象由系统进行管理,它在内存中以链式结构存在。

Linux 单进程内存限制

/etc/security/limits.conf

# shaojiemike @ node5 in ~ [6:35:51]
$ ulimit -a
-t: cpu time (seconds)              unlimited
-f: file size (blocks)              unlimited
-d: data seg size (kbytes)          unlimited
-s: stack size (kbytes)             8192
-c: core file size (blocks)         0
-m: resident set size (kbytes)      unlimited
-u: processes                       513967
-n: file descriptors                1024
-l: locked-in-memory size (kbytes)  65536
-v: address space (kbytes)          unlimited
-x: file locks                      unlimited
-i: pending signals                 513967
-q: bytes in POSIX msg queues       819200
-e: max nice                        0
-r: max rt priority                 0
-N 15:                              unlimited

ulimit -HSn 4096 # H指定了硬性大小,S指定了软性大小,n表示设定单个进程最大的打开文件句柄数量。硬限制是实际的限制,而软限制,是warnning限制,只会做出warning

lsof
文件描述符

文件句柄数

这些限制一般不会限制内存。

超算登录节点任务限制的实现

GNU malloc()

调用malloc(size_t size)函数分配内存成功,总会分配size字节VM(再次强调不是RAM),并返回一个指向刚才所分配内存区域的开端地址。分配的内存会为进程一直保留着,直到你显示地调用free()释放它(当然,整个进程结束,静态和动态分配的内存都会被系统回收)。

GNU libc库提供了二个内存分配函数,分别是malloc()和calloc()。glibc函数malloc()总是通过brk()或mmap()系统调用来满足内存分配需求。函数malloc(),根据不同大小内存要求来选择brk(),还是mmap(),阈值 MMAP_THRESHOLD=128Kbytes是临界值。小块内存(<=128kbytes),会调用brk(),它将数据段的最高地址往更高处推(堆从底部向上增长)。大块内存,则使用mmap()进行匿名映射(设置标志MAP_ANONYMOUS)来分配内存,与堆无关,在堆之外。

malloc不是直接分配内存的,是第一次访问的时候才分配的?

https://www.zhihu.com/question/20836462

问题

  1. 堆区和栈区是进程唯一的吗?
  2. 是的,而且栈主要是为一个线程配备,小可以保证基本在cache里
  3. 两个操作系统的malloc的是物理内存还是虚拟内存
  4. Linux采用的是copy-on-write机制

需要进一步的研究学习

暂无

遇到的问题

暂无

开题缘由、总结、反思、吐槽~~

每次都是6008这里,40000*6008*3/1024/1024=687MB 733448/1024=716MB 问了大师兄,问题竟然是malloc的传入参数错误的类型是int,导致存不下3*40*1024*40*1024。应该用size_t类型。(size_t是跨平台的非负整数安全类型)

参考文献

https://blog.csdn.net/shenzi/article/details/3972437?utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.base&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.base

程序(进程)内存空间分布深入理解

Firewall

简介

防火墙是一种网络安全设备,主要是通过硬件和软件的作用于内部和外部网络的环境间产生一种保护的屏障,从而实现对计算机不安全网络因素的阻断。 * 所有流入流出的所有网络通信均要经过此防火墙。 * 功能 * 访问控制、隔离保护 * 组成 * 服务访问政策、验证工具、包过滤和应用网关

功能作用

  • 入侵检测功能
  • 主要有反端口扫描、检测拒绝服务工具、检测CGI/IIS服务器入侵、检测木马或者网络蠕虫攻击、检测缓冲区溢出攻击等功能,
  • 可以极大程度上减少网络威胁因素的入侵,有效阻挡大多数网络安全攻击。
  • 网络地址转换功能(NAT)
  • 分为源地址转换和目的地址转换,即SNAT和DNAT。可以由服务的发起者是谁来区分两者。
  • SNAT: 内部地址要访问公网上的服务时,内部地址会主动发起连接,将内部地址转换成公有ip
    • 修改源ip地址的目的一般都是为了让这个包能再回到自己这里,所以在iptables中,SNAT是在出口,也即POSTROUTING链发挥作用。
    • SNAT主要用于隐藏内部网络结构,避免受到来自外部网络的非法访问和恶意攻击,有效缓解地址空间的短缺问题,
  • DNAT:当内部需要对外提供服务时,外部发起主动连接公有ip的网关,路由器或着防火墙的网关接收到这个连接,然后把连接转换到内部,此过程是由带公有ip的网关代替内部服务来接收外部的连接,然后在内部做地址转换。
    • 修改目的ip地址的原因一般就是为了改变包发送的目的地,让包走出去,而不是留下来,所以在iptables中,DNAT是在入口,也即PREROUTING链中发挥作用,以便让包进入FORWARD表。
    • DNAT主要用于外网主机访问内网主机,以此避免内部网络被攻击。
    • DNAT与端口转发的区别在哪里?
  • 网络操作的审计监控功能
  • 对系统管理的所有操作以及安全信息进行记录,提供有关网络使用情况的统计数据,方便计算机网络管理以进行信息追踪。
  • 强化网络安全服务(类似GFW)
  • 集中化的安全管理,将安全系统装配在防火墙上,在信息访问的途径中就可以实现对网络信息安全的监管。

Linux实现原理

  • Linux系统内核中的安全框架Netfilter,为其他内核模块提供数据包过滤、网络地址转换(NAT)和负载均衡的功能。
  • 常用的iptables和firewalld服务都依赖于Netfilter来过滤数据包,两者自身并不具备防火墙的功能,只是创建并维护规则。
  • 不同之处在于iptables基于“过滤规则链”,firewalld基于zone区域。
  • iptables无守护进程,不能算作真正的服务,firewalld存在守护进程

三表五链 - 三表(应用规则)

  • filter 用于过滤,防火墙,过滤数据包
  • nat 用于网络地址转换、端口转发
  • mangle 用于拆解报文,作出修改,封装报文
  • raw表, 关闭nat表上启用的连接追踪机制,以提高性能。
  • 表规则应用优先级:raw>mangle>nat>filter
  • 每个表中能存在的链如下

三表五链 - 五链(数据包状态/ 过滤规则链)

  • PREROUTING 进入路由之前的数据包
  • INPUT 目的地址为本机的输入数据包
  • FORWARD 目的地址不为本机的包,可以实现转发(需要开启)
  • OUTPUT 源地址为本机的输出数据包
  • POSTROUTING 发送到网卡之前的数据包

Nftables

  • Allows configuration of tables, chains and rules provided by the Linux kernel firewall.
  • Nftables replaces iptables.
  • 解决的iptables的不足
    • 不同协议实现的代码重复
    • Nftables通过增强的通用集和映射基础结构,可以更快地进行数据包分类。
    • 解决语法不一致的问题,并提供更好,更紧凑的语法。
  • OpenWRT和ubuntu都使用Nftables

与iptables表的对应关系

nftables簇 iptables实用程序
ip iptables
ip6 ip6tables
inet iptables和ip6tables
arp arptables
bridge ebtables
  • ip(即IPv4)是默认簇,如果未指定簇,则使用该簇。
  • 创建同时适用于IPv4和IPv6的规则,请使用inet。inet允许统一ip和ip6簇,以便更容易地定义规则。

输出解释

table inet warp {
        chain warp-in {
                type filter hook input priority mangle; policy accept;
                ip6 saddr 2606:4700:d0::a29f:c001 udp sport 1701 @th,72,24 set 0x0
        }

        chain warp-out {
                type filter hook output priority mangle; policy accept;
                ip6 daddr 2606:4700:d0::a29f:c001 udp dport 1701 @th,72,24 set 0x46c997
        }
}
  • type 可以是filterroute或者nat
  • hook 在IPv4/IPv6/Inet地址簇中,可以是preroutinginputforwardoutput或者postrouting。其他地址簇中的钩子列表请参见nft(8)。

iptables命令

查看默认表filter的规则

对于每条链,内核会按照顺序依次检查 iptables 防火墙规则,如果发现有匹配的规则目录,则立刻执行相关动作,停止继续向下查找规则目录;如果所有的防火墙规则都未能匹配成功,则按照默认策略处理。

$ sudo iptables -vnL 
Chain INPUT (policy ACCEPT 2211K packets, 855M bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 ACCEPT     all  --  tun0   *       0.0.0.0/0            0.0.0.0/0

  • 命令
  • 默认 -t filter
  • -v 显示详细信息,-n显示具体ip和端口数值
  • 输出
  • policy ACCEPT 当前链的默认策略 ACCEPT
  • pkts:对应规则匹配到的报文的个数。
  • bytes:对应匹配到的报文包的大小总和。
  • target:规则对应的target,往往表示规则对应的"动作",即规则匹配成功后需要采取的措施。
  • prot:表示规则对应的协议,是否只针对某些协议应用此规则。
  • opt:表示规则对应的选项。
  • in:表示数据包由哪个接口(网卡)流入,我们可以设置通过哪块网卡流入的报文需要匹配当前规则。
  • out:表示数据包由哪个接口(网卡)流出,我们可以设置通过哪块网卡流出的报文需要匹配当前规则。
  • source:表示规则对应的源头地址,可以是一个IP,也可以是一个网段。
  • destination:表示规则对应的目标地址。可以是一个IP,也可以是一个网段。

添加的动作

命令部分:-j + 如下动作 * ACCEPT:允许数据包通过。 * DROP:直接丢弃数据包,不给任何回应信息,这时候客户端会感觉自己的请求泥牛入海了,过了超时时间才会有反应。 * REJECT:拒绝数据包通过,必要时会给数据发送端一个响应的信息,客户端刚请求就会收到拒绝的信息。 * SNAT:源地址转换,解决内网用户用同一个公网地址上网的问题。 * MASQUERADE:是SNAT的一种特殊形式,适用于动态的、临时会变的ip上。 * DNAT:目标地址转换。 * REDIRECT:在本机做端口映射。 * LOG:在/var/log/messages文件中记录日志信息,然后将数据包传递给下一条规则,也就是说除了记录以外不对数据包做任何其他操作,仍然让下一条规则去匹配。

iptables管理命令

  • 选择表
  • -t指定表
  • 添加新规则
  • -A在链的最后追加一条规则 
  • -I在链的开头或指定序号插入一条规则 
  • -x显示精确值,不做单位换算
  • 替换规则
  • -R替换一条指定的规则
  • 查看规则
  • -L列出所有规则 
  • -n以数据形式显示地址与端口信息 
  • -v以更加详细的方式显示 
  • --line-numbers查看规则时,显示规则序号
  • 删除或清空规则
  • -D删除指定序号的一条规则 
  • -F清空指定表中的所有规则
  • 设置默认策略
  • -P为指定的链设置默认规则
  • 新建规则链
  • -N新建自定义链
  • 重命名链
  • -E重命名自定义链
  • 删除链
  • -X删除自定义空链 
  • -Z计数器清零

常见实例

Add a NAT rule to translate all traffic from the 192.168.0.0/24 subnet to the host's public IP:

$sudo iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j MASQUERADE

$ sudo iptables -t nat -vnL --line-numbers
Chain POSTROUTING (policy ACCEPT 19 packets, 1551 bytes)
num   pkts bytes target     prot opt in     out     source               destination
6        0     0 MASQUERADE  all  --  *      *       192.168.0.0/24       0.0.0.0/0

$ sudo iptables -t nat -D POSTROUTING 6 #delete

有待学习

  • docker相关的iptables的输出
  • OpenWRT上iptables完全是空的,是显示错误还是防火墙用了firewalld
  • node5上的warp的mangle在哪里?

Ubuntu配置

Windows配置

  • 入站规则
  • 出站规则

OpenWRT配置

to finished

需要进一步的研究学习

暂无

遇到的问题

暂无

开题缘由、总结、反思、吐槽~~

参考文献

https://blog.csdn.net/weixin_45649763/article/details/103338747

https://juejin.cn/post/7108726951304495135

https://icloudnative.io/posts/using-nftables/