Skip to content

Commit 6bfa3d1

Browse files
committed
init
0 parents  commit 6bfa3d1

File tree

106 files changed

+7525
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

106 files changed

+7525
-0
lines changed

.gitignore

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Prerequisites
2+
*.d
3+
4+
# Object files
5+
*.o
6+
*.ko
7+
*.obj
8+
*.elf
9+
10+
# Linker output
11+
*.ilk
12+
*.map
13+
*.exp
14+
15+
# Precompiled Headers
16+
*.gch
17+
*.pch
18+
19+
# Libraries
20+
*.lib
21+
*.a
22+
*.la
23+
*.lo
24+
25+
# Shared objects (inc. Windows DLLs)
26+
*.dll
27+
*.so
28+
*.so.*
29+
*.dylib
30+
31+
# Executables
32+
*.exe
33+
*.out
34+
*.app
35+
*.i*86
36+
*.x86_64
37+
*.hex
38+
39+
# Debug files
40+
*.dSYM/
41+
*.su
42+
*.idb
43+
*.pdb
44+
45+
# Kernel Module Compile Results
46+
*.mod*
47+
*.cmd
48+
.tmp_versions/
49+
modules.order
50+
Module.symvers
51+
Mkfile.old
52+
dkms.conf
53+
54+
node_modules
55+
56+
build/

.vscode/settings.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"editor.formatOnSave": true,
3+
"editor.defaultFormatter": "esbenp.prettier-vscode",
4+
"[c]": {
5+
"editor.defaultFormatter": "llvm-vs-code-extensions.vscode-clangd"
6+
},
7+
"[cpp]": {
8+
"editor.defaultFormatter": "llvm-vs-code-extensions.vscode-clangd"
9+
}
10+
}

LICENSE

Lines changed: 427 additions & 0 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<p align="center">
2+
<img width="240" height="240" align="left" style="float: left; margin: 0 10px 0 0;" src="https://upload.wikimedia.org/wikipedia/commons/thumb/3/35/The_C_Programming_Language_logo.svg/800px-The_C_Programming_Language_logo.svg.png" alt="ArchLinuxStudio_CNetworkEncryption"/>
3+
</br>
4+
<h1>Linux 网络编程与加密 WIP</h1>
5+
✨Linux 网络编程与加密 | 本书的路线是分别介绍完成一个加密通讯代理软件所需要的各方面知识,并最终开发出一个此类软件。 同时也会分析各方向有价值的开源库或软件。提供在线网页文档 ✨
6+
7+
</p>
8+
9+
[![Badge](https://img.shields.io/badge/link-CProgrammingEssence-%230088cc.svg)](https://archlinuxstudio.github.io/CNetworkEncryption)
10+
[![Join telegram community and chat about arch linux](https://img.shields.io/discord/628978428019736619?label=&logo=telegram&logoColor=ffffff&color=7389D8&labelColor=6A7EC2&cacheSeconds=60)](https://t.me/FSF_Ministry_of_Truth)
11+
[![Hits](https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https%3A%2F%2Fgithub.com%2FArchLinuxStudio%2FCProgrammingEssence&count_bg=%2379C83D&title_bg=%23555555&icon=&icon_color=%23E7E7E7&title=hits&edge_flat=false)](https://hits.seeyoufarm.com)
12+
[![License: CC BY-SA 4.0](https://img.shields.io/badge/License-CC%20BY--SA%204.0-lightgrey.svg)](https://creativecommons.org/licenses/by-sa/4.0/)
13+
[![Lines](https://img.shields.io/tokei/lines/github/ArchLinuxStudio/CNetworkEncryption)](https://img.shields.io/tokei/lines/github/ArchLinuxStudio/CNetworkEncryption)
14+
[![lastcommit](https://img.shields.io/github/last-commit/ArchLinuxStudio/CNetworkEncryption)](https://img.shields.io/github/last-commit/ArchLinuxStudio/CNetworkEncryption)
15+
16+
<!-- shields not support telegram online count now, use sample discord instead temporarily -->
17+
18+
## [阅读地址](https://archlinuxstudio.github.io/LinuxNetworkProgrammingAndEncryption/#/)
19+
20+
为推动自由软件运动而撰写的 Linux 网络加密教程。你可以通过本教程学会:
21+
22+
- Linux 网络编程的相关知识
23+
- 密码学组建库 mbedtls 以及 sodium 的使用
24+
- 如何实现一个 TLS 的网页请求客户端
25+
- 将各项网络、密码学技术组合,实现互联网的自由访问
26+
27+
## Star 历史
28+
29+
[![Stargazers over time](https://starchart.cc/ArchLinuxStudio/CNetworkEncryption.svg)](https://starchart.cc/ArchLinuxStudio/CNetworkEncryption)

TODO

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
1. 不可破译的一次性密码本(one time pad) 悖论
2+

docs/.nojekyll

Whitespace-only changes.

docs/README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Linux 网络编程与加密 WIP <!-- {docsify-ignore-all} -->
2+
3+
> 这是一个需要长期完成的文档,不要期望短期内完善。这并不代表我们会停止更新,当我们的精力放在此项目时就会进行更新。目前此电子书是我们的第一优先级任务。
4+
5+
本书通过讲述网络编程,密码学技术,以及需要用到的相关密码学库组件,教授一个能够自由访问互联网的通信工具。
6+
7+
本书针对 GNU/Linux 操作系统,全部操作均在 Arch Linux 下完成。没有安装 Linux 的同学可以先参考[Arch Linux 安装使用教程](https://archlinuxstudio.github.io/ArchLinuxTutorial/#/)安装上 Linux。本书的定位是**较为进阶**,对于特别基础的知识,将不会赘述。
8+
9+
网络服务器及 TCP/IP 编程此类话题,它们是相当广阔的、甚至几乎是无止境的。本书只会描述能够完成一个自由访问互联网通信工具所需知识的最小部分。
10+
11+
- 本书特点
12+
13+
- 所有代码没有使用自定义封装的函数或者头文件,均采用 Linux 标准头文件和库函数,直接拷贝即可在 Arch Linux 下编译运行。这是为了保持教程的简洁以及实用性。
14+
- Linux 二次元电报群:[ArchLinuxStudio🇨🇦🏳️‍⚧️🏳️‍🌈](https://t.me/FSF_Ministry_of_Truth)
15+
- 无废话,只给出应当掌握的部分,不会面面俱到。C 语言博大精深,如有错误欢迎直接指出。
16+
- 本书使用 docsify 以及 gitalk 开发,并且网站源码全部开源,可放心留言讨论。
17+
- 只要 C 语言依旧活跃,就会一直更新。[鼓励志愿者提交更新](/contribution.md)
18+
- 本书仅支持 Linux x86_64 环境。根据最新版的 GCC 与 Glibc 更新内容。仅保证全部样例在 Arch Linux 中的可运行性。

docs/_404.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# 404
2+
3+
你所访问的页面目前并不存在,你可以尝试搜索相关内容。或者如果有必要,联系作者创建这个页面。

docs/_sidebar.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
- [**Linux 网络编程与加密**](/)
2+
3+
<!-- - 基础
4+
5+
- [基本概念](/basic/basic_concept)
6+
- [指针与数组](/basic/array_and_pointer) -->
7+
8+
- Socket 编程
9+
10+
- [简要说明](/socket/basic.md)
11+
- I/O 模型
12+
13+
- [阻塞式 I/O 模型](/socket/block)
14+
- [非阻塞式 I/O 模型](/socket/none_block)
15+
- [I/O 多路复用模型](/socket/multiplexing)
16+
- [信号式驱动式 I/O 模型](/socket/signal)
17+
- [异步 I/O 模型](/socket/async)
18+
19+
- 逻辑处理模型
20+
21+
- [WIP](/)
22+
23+
<!-- - [通过 wireshark 抓包认识 socks5](/network/socks5_with_wireshark)
24+
- [Lab0](/network/lab0) -->
25+
<!-- - [阅读 microsocks 的源码](/network/read_with_microsocks) -->
26+
27+
- mbedtls 库与密码学的应用与实践
28+
29+
- [mbedtls 与密码学初步](/libmbedtls/basic)
30+
- [密码学工具箱](/libmbedtls/crypto_toolbox)
31+
- [TLS 客户端的实现](/libmbedtls/tls)
32+
- [Lab1](/libmbedtls/lab1)
33+
34+
- 网络封锁突破
35+
36+
- [基本原理](/fuckgfw/basic)
37+
38+
- libsodium 库的应用与实践
39+
40+
- [libsodium 初步](/libsodium/basic)
41+
- [使用 chacha20-poly1305 加解密](/libsodium/chacha20-poly1305)
42+
- [密钥的派生](/libsodium/key_derivation)
43+
- [辅助函数](/libsodium/helpers)
44+
45+
<!-- - libev 库的应用与实践
46+
47+
- [libev 初步](/libev/basic) -->
48+
49+
<!-- - shadowsocks-libev 的实现
50+
51+
- [shadowsocks-libev 初步](/shadowsocks-libev/basic) -->
52+
53+
- [贡献文档与代码](contribution.md)
54+
- [关于&致谢](about.md)

docs/about.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# 关于&致谢 <!-- {docsify-ignore-all} -->
2+
3+
作为一个在现代社会中生活的人类,自由访问互联网是每个人应有的最基本的权利。但是在某些国家或地区,这一基本权利却被剥夺了。在前十几年,有一部分人还幻想着威权政府的相关部门会做出一些改变和妥协,还大众一个较为自由的言论以及互联网媒体环境,但如今来看,这无异于痴人说梦,我们应该采取行动了。这种情形迫使这些国家或地区的人们需要掌握突破互联网封锁的技术手段,因为只有这样才能最大限度的保证自己对于自由互联网的访问。
4+
5+
世界范围内真正的互联网不是洪水猛兽,它是世界上各个交流的人们彼此交流,互通有无的最佳媒介,通过互联网,世界各地的人们可以平等的交流与学习。对于互联网的封锁从教育方面来说是有百害而无一利的。有价值的各类知识分布在世界各地,也许某些地区的知识价值更高,更值得去学习,但是由于互联网封锁的现状,太多的学生以及计算机从业者由于没有掌握访问自由互联网的技术手段,只能受困于质量惨不忍睹的所在国家或地区的局域网网络,这让人不能不联想到在某个历史进程中"睿智"无比的愚民政策。自信的开放与讨论才是真正的文化自信,在"不敢说"、"不能看"、"不能听"的环境下提出的文化自信只能贻笑大方,这些卑劣的压制审计手段也必将被忠实的记录在历史的长卷中。
6+
7+
本书基于 Linux 内核提供一个学习路线。从网络编程到加密手段,一整套学习的路线下来,你可以掌握对于开发一个加密的、可自由访问互联网的服务器软件所需要的全部技术。关于本书存在的任何问题以及建议,均可以入群讨论,也可以直接在本页下方留言。
8+
9+
感谢持续十余年的,与 GFW 对抗中的广大开发者,如 [clowwindy](https://github.com/clowwindy)[Victoria Raymond](https://github.com/VictoriaRaymond) 以及 [shadowsocks](https://github.com/shadowsocks)[v2ray](https://github.com/v2ray)/[v2fly](https://github.com/v2fly) 社区的各个开发者。你们的代码为后来人提供了太多的启示,同时你们敢于对抗,争取自由的理念也必将激励更多的有识之士投入到这场斗争中来。
10+
11+
Telegram 电报群: [ArchLinuxStudio🇨🇦🏳️‍⚧️🏳️‍🌈](https://t.me/FSF_Ministry_of_Truth)
12+
13+
## 更新日志
14+
15+
- 2021-03-11 项目启动

docs/basic/array_and_pointer.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# 指针与数组
2+
3+
本节针对指针与数组描述一些需要注意的知识点。
4+
5+
## 数组下标为何从 0 开始
6+
7+
因为下标实际代表的是一个偏移量,它表示当前要引用的元素到数组中第一个元素之间有多少个元素偏移。
8+
9+
## 指针退化
10+
11+
考虑如下代码
12+
13+
[pointer_degeneration](../src/basic/pointer_degeneration.c ':include')
14+
15+
当把数组赋值给指针变量时,指针变量只会包含数组的地址内容相关信息,而对于数组的长度会丢失,这种情况一般被称为指针退化。一个常见的场景是,在将数组变量传递给函数数组形参时,此种现象发生,因为函参数组实际上被当作指针处理,此时计算长度应用 strlen,而不是 sizeof。
16+
17+
## 数组变量指向不可变
18+
19+
创建指针变量时,会为变量分配存储空间。但是创建数组变量时,不会为数组变量分配空间,仅为数组分配空间。编译器仅在数组变量出现的地方将其替换成数组的起始地址。由于数组变量没有被分配空间,所以其不能像指针变量一样指向其他地方。
20+
21+
## 指针变量为何有类型
22+
23+
因为在进行指针加减运算时,需要根据类型来计算在存储器中的地址偏移。如果对 char 指针加 1,指针会指向存储器中下一个地址,因为 char 就占一个字节。如果是 int 指针加 1,那么会对存储器地址加 4,因为 int 占四个字节。
24+
25+
## 数组变量的交换率
26+
27+
考虑如下代码
28+
29+
[array_exchange_rate](../src/basic/array_exchange_rate.c ':include')
30+
31+
这种操作数组变量的方式不太常见,其实它是一个操作数组变量的交换率。我们操作数组时往往写成 `does[3]`这种形式,其与`*(does+3)`是等价的。而`*(does+3)``*(3+does)`等价,最终我们得到`*(3+does)``3[does]`等价
32+
33+
## 注意字符串常量的不可变性
34+
35+
考虑如下代码
36+
37+
[constant_string](../src/basic/constant_string.c ':include')
38+
39+
这段代码不能如期运行。因为指针指向了字符串常量,而字符串常量是不可变的,这是新手经常容易犯的错误。想要代码如期运行,可以使用字符数组替代指针变量`char cards[]="JQK"`。原因是字符数组会复制一份字符串常量的值到栈中,因而可以修改,而指针直接指向常量区,所以不可修改。如在代码中一定要使用指针变量指向常量,可以用 const 关键字修饰指针变量,这样在尝试修改时,编译即会报错。

docs/basic/basic_concept.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# 基本概念与 tricks
2+
3+
本节描述一些很基础,但是容易被忽略的知识点,以及一些看起来写法很简单,但是另含玄机的代码。
4+
5+
## 获取 glibc
6+
7+
ArchLinux 中只有 glibc 的头文件,源代码需要在[官网](https://www.gnu.org/software/libc/started.html)额外下载。在查看源码时,需要注意比如 system 库函数的实现,其定义在头文件 stdlib.h 中,但其实现不在 stdlib.c,一般在同名 c 文件中,此处是 system.c 文件中的 do_system 函数。
8+
有关时效性,可以注意源码中的 change log,如 system 函数的实现已经从原来的 fork+exec 的方式在 2018 年改为使用 posix_spawn 了。
9+
10+
## 条件判断中的位运算符
11+
12+
条件判断中常使用`||`以及`&&`运算符来判断``以及``条件。而位运算符`|`以及`&`也可以应在条件判断中,只不过它们不会像`||`以及`&&`一样存在短路现象,它们总是会计算运算符前后两个条件。
13+
14+
## 输入的陷阱
15+
16+
输入常使用 scanf 与 fgets,二者各有优点。虽然很常见而且简单,也有需要注意的问题。考虑如下代码
17+
18+
[input](../src/basic/input.c ':include')
19+
20+
代码尝试输入得到两个字符,并输出。但是实际你并不能得到期望的输出。在输出第一个字符后,第二个字符的内容为空。
21+
22+
```bash
23+
$ ./a.out
24+
a b
25+
output: b
26+
output:
27+
```
28+
29+
这是因为 scanf 在输入完成后会在 stdin 中遗留一个换行符,我们通常进行多次输入时没有问题的原因是除了%c 和%[...] 这种正则输入形式,其余格式 scanf 都会处理掉前置的 whitespace。比如常用的%f 就会处理掉遗留的换行符。如果比如一定要用%c 连续输入,那么需要在后续的%c 前加一个前导空格来匹配格式。
30+
31+
除此之外,如果 scanf 所接受的是带有文本的输入形式,如`scanf("order=&d", order)`,scanf 也是不会处理 stdin 中遗留的换行符的,在连续多次 scanf 输入格式化文本时,也要在格式化文本前加入空格,如`scanf(" order=&d", order)`
32+
33+
而 fgets 的问题是,首先它仅能用来输入字符串。其次,当所输入的内容,再加上一个`\0`还是不能填满数组时,fgets 会在字符串的最后直接接上一个换行符。这个行为和 scanf 是不同的,scanf 是会在 stdin 中遗留换行符,而 fgets 是会直接加上。
34+
35+
## scanf 的整行输入
36+
37+
scanf 在接收字符串时,遇到空格便会终止,导致随后的字符串无法接收。这时可以用 fgets 来接收整行字符串,也可以使用正则表达式形式的 scanf 来接收包含空格的全部字符串。
38+
39+
[scanf_with_whole_line](../src/basic/scanf_with_whole_line.c ':include')
40+
41+
符号`^`代表取反,整个正则的含义即为取除了`\n`以外的整行全部字符。
42+
43+
## 大类型变量存入小类型变量 为何会出现负数
44+
45+
假设 x 是一个 int 类型的变量,占四字节,其存储 100 000 的值,对应的二进制为`0001 1000 0110 1010 0000`。将其赋给 short 类型的 y,y 只有两字节,所以只能保存二进制数值的靠右部分,即`1000 0110 1010 0000`,最高位的 1 在二进制有符号数会被当最负数处理,即其等价于十进制的`-31072`

docs/c.png

48.5 KB
Loading

docs/c.svg

Lines changed: 1 addition & 0 deletions
Loading

docs/contribution.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# 贡献文档与代码 <!-- {docsify-ignore-all} -->
2+
3+
点击本文右上角的 github 图标,即可查看本工程。在每一页的最下方也有`编辑本文`的链接,点击即可跳转到 github 编辑。
4+
本书的大纲目录由作者把控,文章内容可自由编辑。
5+
6+
## 文档贡献
7+
8+
文档贡献非常简单,你只需要拥有一个编辑器,将工程 fork,修改,提交 pull request 即可。
9+
10+
## 格式约定
11+
12+
本系列文档的理念是不必过于苛求格式,因为内容才是真正重要的东西。但是也有少量规范必需遵守,否则会影响阅读。
13+
14+
- 使用 OSS code 进行开发,配合 Prettier 插件默认配置进行格式化代码,写完部分文档后使用 ctrl+s 自动格式化保存。
15+
- 每个 md 文档标题按层级编排内容,大标题为#,其次##,再次###,以此类推。
16+
- 代表片段需用 markdown 语法包裹,并指定代码类型,如 bash。
17+
- 一般情况下,请尽量正常使用句号、顿号、引号、冒号等标点符号。
18+
- 需要引起注意的部分可使用 markdown 引用语法。
19+
- 专有名词可使用行内代码``语法进行提示,其比加粗更为明显。
20+
- 行内代码请使用行内代码进行提示。
21+
22+
## 代码贡献
23+
24+
本工程使用 [docsify](https://docsify.js.org/#/) 编写而成。如果想贡献相关代码请先阅读 docsify 的项目文档。
25+
26+
本工程使用 yarn 管理依赖,结构非常简单。如果没有接触过,你可能需要简单了解一下[yarn](https://classic.yarnpkg.com/en/)
27+
28+
本地调试
29+
30+
```bash
31+
yarn install
32+
yarn start
33+
```

docs/fuckgfw/basic.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# 基本原理
2+
3+
在前面的两章,分别介绍了网络编程与密码学的知识,并且在最后实现了一个代理工具。但是这个代理工具仅仅是为了以最简要的形式说明运行的原理,并不具备实用性。本章将以火狐浏览器作为客户端,来实现一个为浏览器服务的代理工具。
4+
5+
实际上,网络封锁的突破本质上就是转发与加密的结合。转发可以将流量发送到远端以及将流量接收到本机,加密可以保证转发的过程是安全的,不被解析以及拦截。
6+
7+
对于转发的部分,实际上就是传统意义上的代理,关于这部分内容,可以参考《HTTP 权威指南》一书中第四章、第六章以及第八章中的内容,在这些章节中有详尽的描述。需要注意的是,这些章节中对于改写 HTTP 代理中接收到的完整路径为相对路径的步骤应该可以省略了,因为其是为兼容 HTTP1.0 中无 HOST 的情况。除此之外,改写 Proxy-Connection 到 Connection 的操作也不是必要的了,因为在 HTTP1.1 中以及默认均为长链接,对于兼容 HTTP1.0 的情况下会出现的问题可详见书中的讨论。
8+
9+
对于加密的部分,是为了不让互联网审计系统能够检测到通讯内容,或者发现流量特征。一般网络封锁突破软件会通过预配置的方式实现加密密码的共享,也即在本机和远端服务器事先设置好密码与相关配置。
10+
11+
本章将以[mproxy](https://github.com/ArchLinuxStudio/mproxy)项目为范例,讲解一个能实际使用的代理软件是如何工作的。当然,mproxy 也只是一个范例程序,其中有很多不完善的地方,但其足以能够说明代理的工作方式。

0 commit comments

Comments
 (0)