V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  liuxu  ›  全部回复第 30 页 / 共 146 页
回复总数  2904
1 ... 26  27  28  29  30  31  32  33  34  35 ... 146  
2021-10-29 17:15:10 +08:00
回复了 huangmingyou 创建的主题 Kubernetes 老问题,现在流行什么方法管理多个环境下的 k8s 项目
我是一个 helm 包下面多个 values.yaml ,helm 可以指定 value 文件 --values xx.yaml
2021-10-27 21:21:46 +08:00
回复了 ysy950803 创建的主题 PHP PHP 服务挂了之后是不是就能查看. PHP 文件源码了?
#97 s/不会暴露密码 /不会暴露代码 /
2021-10-27 21:11:14 +08:00
回复了 ysy950803 创建的主题 PHP PHP 服务挂了之后是不是就能查看. PHP 文件源码了?
首先我忘了回复楼主。
1. 如果 php 文件和 index.html 同目录,但是 nginx 配置文件配置了请求 php 路径的 location ,不会暴露密码。
2. 如果 test.php 不渲染任何东西,但是 nginx 通过 fastcgi 访问 fpm ,fpm 运行 test.php 后实际上会返回 http 200 OK ,nginx 会把这个返回给浏览器,所以浏览器显示空白是正常情况,但是你如果观察 header ,是有对应的 header 头的。显示空白只是 http 的 content 是空的而已。
3. 如果满足 1 的配置要求,fpm 挂了,nginx 一般是抛出 502 错误页。
4. 只有没有按 1 的要求配置,才会返回 php 代码文件。



@void1900
@hxy100

我不是想打谁的脸,我回复的目的主要是为 25 楼这样的小兄弟解答,以及其他看到这个帖子的新人。
我看各位的注册年限都好几年,工作经验起码 3-5 年以上了,也正是因为这个原因,你们对技术比较专业的讨论,如果没有正确的回复,会非常误导人。

下面的回复不是针对谁,我就是给其他刚入行的小兄弟看的。

问:后缀是不是 MIME media type ?
答:不是。
原因:
1. 从理论角度来分析,MIME 是有 RFC 的,但是 RFC 中并没有任何有关后缀和 media type 的关系定义。
image/png 中,image 是 type ,png 是 subtype ,中间用 /分开,为一个 MIME media type 。而.png 没有任何定义。
https://en.wikipedia.org/wiki/MIME

2. MIME media type 的列表是 IANA 定制的,而且大部分也说明了 MIME media type 对应的文件后缀,下面以 text/html 为例,见“File extension”部分。
https://www.iana.org/assignments/media-types/text/html

那么从以上两点可以知道 MIME 是 MIME ,文件后缀是文件后缀。




说到这里我想扩展一下。

1. 一个软件(nginx, file)识别一个文件的 MIME 有 2 中方法。
a. 像 nginx 一样提供一个 mime.types 这样的有 mime 和文件后缀对应的列表。
b. 像 linux 命令 file 一样分析文件内容。

按 a 的话效率很高,毕竟分析文件内容会导致 nginx 消耗额外资源,而且只要配置列表齐全,就不会出现不识别问题。
而 file 是按 b ,所以 file 判断一个文件 test.php 文件的时候,把文件名改成 test ,也就是删掉.php ,也可以识别正确。原理是看文件是不是"<?php"开头。

$ cat test.php
<?php

t$ file --mime test.php
test.php: text/x-php; charset=us-ascii

$ mv test.php test

$ file --mime test
test: text/x-php; charset=us-ascii

但是这个是有缺陷的, 因为 php 可以 html 和 php 代码混合。
$ cat test
<!DOCTYPE html>
<html>
<body>
<?php
echo "I'm liuxu.\n";
?>
</html>

$ php test
<!DOCTYPE html>
<html>
<body>
I'm liuxu.
</html>

$ file --mime test
test: text/html; charset=us-ascii

可以看到明明是 php 文件,但是 file 却说文件是 text/html ,因为 file 读取文件开头是"<!DOCTYPE html>",所以判断这个文件是 html 文件。
同时也可以看见即使没有.php 后缀,文件也可以识别执行。原因是 php 读取文件就是单纯的 fopen()。


问:那么我用 php 执行一个单纯的 html 会怎样,甚至是一个 txt 会怎样。
答:会原样输出文件内容。
$ cat test.html
<!DOCTYPE html>
<html>
<body>
</html>

$ php test.html
<!DOCTYPE html>
<html>
<body>
</html>




2. nginx+php-fpm 的原理,我就以 nginx 官方配置说明为例。
server {
location / {
fastcgi_pass localhost:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param QUERY_STRING $query_string;
}

location ~ \.(gif|jpg|png)$ {
root /data/images;
}
}

首先这个配置没有匹配.php 后缀,而是匹配所有请求。如果请求时.gif .jpg .png 结尾,则会去 /data/images/加上请求路径拼接查找对应文件,也就是请求 /test/a.jpg ,会查找 /data/images/test/a.jpg 。然后如果找到了文件,会根据后缀.jpg 在 mime.types 查找到 mime 设置到 Content-Type ,然后返回。

但是如果不是上面的请求后缀,则转发到后端 php-fpm 。转发整个过程是:
a. 匹配请求路径,如 /test1.html ,/test2.php 。
b. 设置 fastcgi_param SCRIPT_FILENAME ,设置的值为 root 目录加请求路径,也就是 root 是 /data/project/,请求是 /test2.php 的话,SCRIPT_FILENAME 为 /data/project/test2.php 。然后把这个路径发送给 php-fpm 。php-fpm 使用 fopen()打开这个文件,由于是绝对路径,所以 php-fpm 不会读取到错误的工作目录。然后 php 执行 test.php ,得到输出返回给 nginx ,包含 header ,最后 nginx 做一些其他操作后将 php-fpm 的返回值返回给浏览器。

所以从 b 的的解析来看,即使你请求"/test3",也就是没有后缀,那么假如 /data/project/test3 问一个 php 内容的文件,php-fpm 一样会执行返回。




3. 然后我普及下十几年前 asp/php 当道的年代,一个人尽皆知的 webshell 攻击手法,也是和 mime 有关。
a. 首先网站有个上传图片功能,php 验证文件的方式是读取文件的 mime ,也就是看是不是 image/jpeg 或者 image/png 。
b. 攻击者上传 muma.php ,由于这个会上传时 Content-type 不是 image/jpeg ,所以使用工具劫持请求,然后更改上传文件的 Content-type 为 image/jpeg 后发送请求。然后 php 会验证通过,将文件存放到磁盘上。最后攻击者访问这个文件的链接就拿到了 webshell ,所以现在 php 验证一般是验证文件后缀。这也是说明 mime 和文件后缀虽然有联系,但是要区分对待。



4. 最后我想说一下 php 的 mime 问题,有点意思。从我查询有限的信息来看,php 是有 mime 的,但是还没有被 IANA 收录。
首先 IANA 定义的 MIME media type 叫官方 MIME ,然后还有一些 subtype 为 x-开头的,叫非官方定义,为的是以后官方定义避免名字冲突所以加上了 x-。
现在就有一个有趣的事情,我看前面有人说 apache 中 php 的 mime 要设置成 application/x-httpd-php ,实际上 linux 都有一个文件,叫 /etc/mime.types ,里面有 IANA 定义的 MIME 列表,但是 php 相关是注释掉的。
$ cat /etc/mime.types | grep php
#application/x-httpd-php phtml pht php
#application/x-httpd-php-source phps
#application/x-httpd-php3 php3
#application/x-httpd-php3-preprocessed php3p
#application/x-httpd-php4 php4
#application/x-httpd-php5 php5

然后用 file 看 php 文件的 mime 是 text/x-php 。

$ file -i test.php
test.php: text/x-php; charset=us-ascii

这个其实很有趣,原因是命名规范问题。

首先有官方定义 application/javascript 和 text/html ,原因是 js 是程序代码,html 是 html 文本。但是 php 很特殊,因为 php 可以是单纯的<?php 开头的 php 文件,也可以是 html+php 混合文件。如果是混合文件,那么开头就是<!DOCTYPE html>或者<html>,这样读取分析文件会是 text/html ,明显是错的。然后有人说 application/x-httpd-php 这个是有问题的,因为 php 和 html 一样是可读文本,所以 type 应该是 text ,mime 应该是 text/x-php 。所以 IANA 应该是考虑到这个问题,就把 php 相关的 mime 去掉的。但是 apahce 现在还在用,linux 命令 file 或者 php 自己的方法 mime_content_type()返回 php 文件的 mime 都是 text/x-php 。
2021-10-27 00:08:46 +08:00
回复了 ysy950803 创建的主题 PHP PHP 服务挂了之后是不是就能查看. PHP 文件源码了?
@jindeq
@void1900
@hxy100

直接用 nginx 源码讲话。


首先说明 nginx 的默认配置 mime.types ,内容如:
types {
text/html html htm shtml;
text/css css;
text/xml xml;
...

存储在 nginx 内存中方存放的方式为:
[
'html' => 'text/html',
'htm' => 'text/html',
'shtml' => 'text/html',
'css' => 'text/css',
'xml' => 'text/xml',
...
]
也就是['ext' => 'mime']这种格式,从这里就很清楚了,mime 和文件后缀可以互相替代,但是 mime 不是文件后缀,你完全可以在这个文件里添加一条
text/html v2ex;

此后后缀为".v2ex"的文件 nginx 返回时 response 的 Content-type 就会设置成 text/html

liuxu@liuxu-VirtualBox:/etc/nginx$ cat mime.types | grep v2ex
text/html v2ex;

liuxu@liuxu-VirtualBox:/etc/nginx$ ls -l /var/www/html/
total 12
-rw-r--r-- 1 root root 612 10 月 26 21:47 index.nginx-debian.html
-rw-r--r-- 1 root root 11 10 月 26 23:34 test.v2ex

liuxu@liuxu-VirtualBox:/etc/nginx$ file /var/www/html/index.nginx-debian.html
/var/www/html/index.nginx-debian.html: HTML document, ASCII text

liuxu@liuxu-VirtualBox:/etc/nginx$ file /var/www/html/test.v2ex
/var/www/html/test.v2ex: ASCII text

liuxu@liuxu-VirtualBox:/etc/nginx$ cat /var/www/html/test.v2ex
I'm liuxu.

liuxu@liuxu-VirtualBox:/etc/nginx$ curl -v http://127.0.0.1/test.v2ex
* Trying 127.0.0.1:80...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 80 (#0)
> GET /test.v2ex HTTP/1.1
> Host: 127.0.0.1
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: nginx/1.18.0 (Ubuntu)
< Date: Tue, 26 Oct 2021 15:35:53 GMT
< Content-Type: text/html
< Content-Length: 11
< Last-Modified: Tue, 26 Oct 2021 15:34:36 GMT
< Connection: keep-alive
< ETag: "6178200c-b"
< Accept-Ranges: bytes
<
I'm liuxu.
* Connection #0 to host 127.0.0.1 left intact



在有了以上说明后,下面从 nginx 源码说话:

1. nginx 不设置 default_type 时,response 的 Content-Type 默认是 text/plain ,而不是 application/octet-stream 。也就是说单独一个 nginx 运行,root 目录为 /var/www/html/时,把 test.php 放入 /var/www/html/下,会直接打印代码。

https://github.com/nginx/nginx/blob/41a241b3ef74dbbe3d82ab2ebbe682919e4a0b90/src/http/ngx_http_core_module.c#L3693

2. nginx 设置了 default_type 为 application/octet-stream ,按 1 的配置,浏览器访问 1.php ,Content-Type 因为是 application/octet-stream 所以会下载该文件。当然也不止 application/octet-stream ,还有如果有 Content-Disposition 的话也会调用下载任务。
https://en.wikipedia.org/wiki/MIME

3. nginx 引入了自己的默认配置文件 mime.types 后,ngx_http_set_content_type()首先走到 1606 行判断有没有文件后缀,如果有后缀,则会走到 1633 ,从后缀中搜索 type ,也就是前面说的在 nginx 内存结构中的 mime.types:
type = ngx_hash_find(&clcf->types_hash, hash,
r->exten.data, r->exten.len)
if (type) {
r->headers_out.content_type_len = type->len;
r->headers_out.content_type = *type;

return NGX_OK;
}
但是由于 mime.types 中没有 php 相关的配置,也就是不存在一个"type/xxx php"这样的配置,所以如果没有设置 location ~ \.php${...}这类配置,php 文件就会被下载。

以下是返回 response 的代码:
https://github.com/nginx/nginx/blob/41a241b3ef74dbbe3d82ab2ebbe682919e4a0b90/src/http/ngx_http_core_module.c#L1593



所以 nginx 并没有通过 mime 来区分返回 response ,而是通过文件后缀查询到了对应的 mime ,然后设置了到 Content-type 然后返回。

最后说一下 location ~ \.php${...}中,.php 是不是后缀匹配。从人为理解来说是匹配.php 后缀文件,但是从 nginx 的角度来看,它就是一个正则字符串,并没有在内部 mime 列表中查出一个['php'=>'type/php']这种东西。
2021-10-26 19:18:06 +08:00
回复了 Geekerstar 创建的主题 MySQL Mysql 中的 JSON 字段如何清洗出来?
mysql5.7 支持 JSON 类型,然后创建虚拟字段或者直接 ORM
2021-10-25 21:15:33 +08:00
回复了 slidoooor 创建的主题 程序员 整理了一波计算机书籍的综合评分列表
其实这个书籍排行榜没意义,应该和 jd 一样弄成同类书籍排行榜,我要看 linux 内核解析只能选那几本,虽然排名很低
2021-10-25 21:13:50 +08:00
回复了 LxnChan 创建的主题 Linux VNC 反代出去总是被爆破,又不想把黑名单设置为 0
fail2ban 解君愁
@liuxu 不过有的 vps 没有用 NetworkManager.service
$ journalctl -u NetworkManager --no-tail |grep dhclient
2021-10-24 14:06:04 +08:00
回复了 mingl0280 创建的主题 C++ 问个关于内存对齐的问题
还有一种情况,系统和编译器都是 64 位,编译目标编译出了 32 位和 64 位程序,debug 分析的时候选择了 32 位程序。
2021-10-24 14:01:37 +08:00
回复了 mingl0280 创建的主题 C++ 问个关于内存对齐的问题
@liuxu #17 修正一下,我之前是 32 位系统 debug 的,现在都是 64 位系统,情况有变化。

首先说结论:
1. 和编译的目标程序的位数有关,32 位程序最高是 4 字节(32 位)对齐,64 位程序最高是(8 字节)64 位对齐。
2. 在 1 的要求下,struct 中按最宽位数的变量对齐。结合 1 中的“最高”的意思是:
64 位程序:uint32_t + uint64_t + uint64_t 分配 24 字节(8+8+8)。
32 位程序:uint32_t + uint64_t + uint64_t 分配 20 字节(4+(4+4)+(4+4))。
32/64 位程序:uint8_t +uint16_t +uint8_t 分配 8 字节(2+2+2)。
3. 添加#pragma pack(4)后,32 位和 64 位程序都按 4 字节(32 位)对齐,也就是 uint32_t + uint64_t + uint64_t 都是 20 字节(4+(4+4)+(4+4))。但是如果 struct 最大为 uint16_t ,则依然按 2 字节对齐。(也就是说 pack 无法影响 struct 最大位宽限制)
4. 添加了#pragma pack(16)后,64 位依然按 8 字节(64 位)对齐。也就是说 pack 中的数字只能是不大于(系统位数 /8)的 2 的次方的数字。


所以楼主的情况, 如果代码中真的没有#pragma pack(),但是出现了帖子中的现象,只有可能是以下 3 中情况:
1. 楼主的系统是 32 位的。( 32 位系统只会运行 32 位编译器编译出 32 位程序)
2. 楼主的编译器是 32 位的。( 32 位编译器只会编译出 32 位程序)
3. 楼主 64 位 msvc 编译目标选择的是 32 位程序。(据我所知 vs 默认的 debuging 版本编译的是 32 位程序,至少我几年前 debug 的时候是的,也有可能是我创建项目的时候设置成了 32 位)。

即楼主 2 次编译的字节对齐方式为:
struct FixedLengthHeader {
uint32_t HeaderSize = 0;
uint64_t CryptogramSize = 0;
uint64_t ReservedField = 0;
}FixedPackageHeaders;
20 字节(4+(4+4)+(4+4))。

struct FixedLengthHeader {
uint32_t HeaderSize = 0;
uint64_t CryptogramSize = 0;
uint8_t DevFlag = 0;
uint8_t HeaderVer = 0;
uint32_t PackagerVer = 0;
uint16_t Reserved = 0
}FixedPackageHeaders;
24 字节(4+(4+4)+4+4+4)。

以上是 64 位 linux gcc 下的结果推测的 msvc 的结果,windows 下的实际结果还是得大佬们自己调试。



以下是我 GDB 打印情况:
系统:Ubuntu 20.04.3 LTS x86_64
gcc: gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0


没有添加#progma pack(4),编译指令:gcc -g test.c

/* offset | size */ type = struct FixedLengthHeader {
/* 0 | 4 */ uint32_t HeaderSize;
/* XXX 4-byte hole */
/* 8 | 8 */ uint64_t CryptogramSize;
/* 16 | 8 */ uint64_t ReservedField;

/* total size (bytes): 24 */
}
(8+8+8)

/* offset | size */ type = struct FixedLengthHeader {
/* 0 | 4 */ uint32_t HeaderSize;
/* XXX 4-byte hole */
/* 8 | 8 */ uint64_t CryptogramSize;
/* 16 | 1 */ uint8_t DevFlag;
/* 17 | 1 */ uint8_t HeaderVer;
/* XXX 2-byte hole */
/* 20 | 4 */ uint32_t PackagerVer;
/* 24 | 2 */ uint16_t Reserved;
/* XXX 6-byte padding */

/* total size (bytes): 32 */
}
(8+8+8)

/* offset | size */ type = struct FixedLengthHeader {
/* 0 | 4 */ uint32_t HeaderSize;
/* 4 | 1 */ uint8_t DevFlag;
/* 5 | 1 */ uint8_t HeaderVer;
/* XXX 2-byte hole */
/* 8 | 4 */ uint32_t PackagerVer;
/* 12 | 2 */ uint16_t Reserved;
/* XXX 2-byte padding */

/* total size (bytes): 16 */
}
(4+4+4+4)


没有添加#progma pack(4),编译指令:gcc -m32 -g test.c

/* offset | size */ type = struct FixedLengthHeader {
/* 0 | 4 */ uint32_t HeaderSize;
/* 4 | 8 */ uint64_t CryptogramSize;
/* 12 | 8 */ uint64_t ReservedField;

/* total size (bytes): 20 */
}
(4+(4+4)+(4+4))

/* offset | size */ type = struct FixedLengthHeader {
/* 0 | 4 */ uint32_t HeaderSize;
/* 4 | 8 */ uint64_t CryptogramSize;
/* 12 | 1 */ uint8_t DevFlag;
/* 13 | 1 */ uint8_t HeaderVer;
/* XXX 2-byte hole */
/* 16 | 4 */ uint32_t PackagerVer;
/* 20 | 2 */ uint16_t Reserved;
/* XXX 2-byte padding */

/* total size (bytes): 24 */
}
(4+(4+4)+4+4+4)


添加#progma pack(4),编译指令:gcc -g test.c

/* offset | size */ type = struct FixedLengthHeader {
/* 0 | 4 */ uint32_t HeaderSize;
/* 4 | 8 */ uint64_t CryptogramSize;
/* 12 | 8 */ uint64_t ReservedField;

/* total size (bytes): 20 */
}
(4+(4+4)+(4+4))

/* offset | size */ type = struct FixedLengthHeader {
/* 0 | 4 */ uint32_t HeaderSize;
/* 4 | 8 */ uint64_t CryptogramSize;
/* 12 | 1 */ uint8_t DevFlag;
/* 13 | 1 */ uint8_t HeaderVer;
/* XXX 2-byte hole */
/* 16 | 4 */ uint32_t PackagerVer;
/* 20 | 2 */ uint16_t Reserved;
/* XXX 2-byte padding */

/* total size (bytes): 24 */
}
(4+(4+4)+4+4+4)


添加#progma pack(16),编译指令:gcc -g test.c

/* offset | size */ type = struct FixedLengthHeader {
/* 0 | 4 */ uint32_t HeaderSize;
/* XXX 4-byte hole */
/* 8 | 8 */ uint64_t CryptogramSize;
/* 16 | 1 */ uint8_t DevFlag;
/* 17 | 1 */ uint8_t HeaderVer;
/* XXX 2-byte hole */
/* 20 | 4 */ uint32_t PackagerVer;
/* 24 | 2 */ uint16_t Reserved;
/* XXX 6-byte padding */

/* total size (bytes): 32 */
}
(8+8+8+8)
2021-10-23 11:17:31 +08:00
回复了 mingl0280 创建的主题 C++ 问个关于内存对齐的问题
你下面的不是
24 字节(4+8+2+2+4+4 )
而是
24 字节(4+8+4+4+4 )

你试试
struct FixedLengthHeader {
uint32_t HeaderSize = 0;
uint64_t CryptogramSize = 0;
uint8_t DevFlag = 0;
uint8_t HeaderVer = 0;
uint16_t Reserved = 0;
uint32_t PackagerVer = 0;
}FixedPackageHeaders;

应该会变成 4+8+4+4=20

应该是编译器优化结果

8|8|32 的位地址占用情况应该是
1111 1111 1111 1111 xxxx xxxx xxxx xxxx
1111 1111 1111 1111 1111 1111 1111 1111
也就是 2 个 8 后面空着不要了

但是如果 8|8|8/16|32,不会再多分配内存,继续复用没有用的 16 位空间
@jdz rust 强力支撑不是我说的,是作者说的,原因是用了 rust 正则引擎
但是不应该对用了几十年的老工具抱有轻蔑的态度,毕竟互联网能发展起来它们是基石
那是自然,rust 强力支撑
@LxnChan

《 Debian 11 是默认不带 GUI 了吗,装完之后没有桌面,安装的时候也没看到选择软件的部分》

你这个标题有 2 个逗号

第一个逗号前是说默认不带 GUI 了吗(截图,带了)
第二个逗号前是安装之后没有桌面(截图,因为带了,所以选择安装就有了)
第二个逗号是说安装没有看到软件选择部分(截图就是选择软件部分,有 GUI 还有 web server 和 ssh server,以及系统工具)

我应该没理解错吧。。
debian-11.1.0-amd64-netinst.iso

这不是有么

https://i.imgur.com/NCEzRil.png
2021-10-19 10:39:20 +08:00
回复了 sherlock1122 创建的主题 Linux 把开发机升级到了 Fedora 35,然后...
可以试试 ubuntu20.04 ,生产开发服务器桌面都行
你什么程序,原则上屏幕是 acpi 管理,只有硬件中断事件会影响它
1 ... 26  27  28  29  30  31  32  33  34  35 ... 146  
关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   Solana   ·   968 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 34ms · UTC 22:44 · PVG 06:44 · LAX 14:44 · JFK 17:44
♥ Do have faith in what you're doing.