0%

在将 m3u8ts 等文件下载完毕后,通过以下命令转换成 mp4 格式视频。

1
$ ffmpeg -allowed_extensions ALL -protocol_whitelist "file,https,tls,http,crypto,tcp" -i ./index.m3u8_backup -c copy ~/Downloads/神奇女侠1984.mp4

但播放 mp4 视频时,发现没有对应中文字幕。但源网站是有的,说明字幕是单独加载的,未添加到视频流中。

阅读全文 »

探索 PHP 字符串压缩,与 node 中 zlib、pako 库压缩、解压缩处理。

  • DEFLATE,是一种使用 Lempel-Ziv 压缩算法(LZ77)和哈夫曼编码的压缩格式。详见 RFC 1951
  • ZLIB,是一种使用 DEFLATE 的压缩格式,对应 HTTP 中的 Content-Encoding: deflate。详见 RFC 1950
  • GZIP,也是一种使用 DEFLATE 的压缩格式,对应 HTTP 中的 Content-Encoding: gzip。详见 RFC 1952

Content-Encoding 中的 deflate,实际上是 ZLIB。ZLIB 和 GZIP 都是 RAW DEFLATE 的不同 Wrapper。

PHP 字符串压缩函数

  • gzcompress ,对应解压缩函数:gzuncompress,使用 raw ZLIB 数据格式。
  • gzdeflate,对应解压缩函数:gzinflate,使用 raw DEFLATE 数据格式。
  • gzencode,对应解压缩函数:gzdecode,压缩成 gzip 编码数据。
  • bzcompress,对应解压缩函数:bzdecompress,压缩成 bzip2 编码数据。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
echo base64_encode(gzdeflate('1234'));
// output: MzQyNgEA
echo gzinflate(base64_decode("MzQyNgEA"));
// output: 1234
echo base64_encode(gzdeflate('1234', 6, ZLIB_ENCODING_DEFLATE));
// output: eJwzNDI2AQAB+ADL
echo gzinflate(base64_decode("eJwzNDI2AQAB+ADL"));
// error: PHP Warning: gzinflate(): data error in php shell code on line 1

echo base64_encode(gzcompress('1234'));
// output: eJwzNDI2AQAB+ADL
echo gzuncompress(base64_decode("eJwzNDI2AQAB+ADL"));
// output: 1234

echo base64_encode(gzencode('1234'));
// output: H4sIAAAAAAAAAzM0MjYBAKPg45sEAAAA
echo gzdecode(base64_decode("H4sIAAAAAAAAAzM0MjYBAKPg45sEAAAA"));
// output: 1234

echo base64_encode(bzcompress('1234'));
// 因当前环境未激活 bzip2 支持,所以暂未测试。需在编译 PHP 时增加 `--with-bz2[=DIR]` 配置项。

pako

1
npm install pako@1.0.6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const pako = require('pako');

function btoa(str) {
return Buffer.from(str).toString('base64');
}

function atob(b64Encoded) {
return Buffer.from(b64Encoded, 'base64');
}

var zipResult = btoa(pako.deflate("1234"));
console.log(zipResult);
// output: eJwzNDI2AQAB+ADL
var unzipResult = pako.inflate(atob("eJwzNDI2AQAB+ADL"), { to: 'string' });
console.log(unzipResult);
// output: 1234

var zipResult = btoa(pako.gzip("1234"));
console.log(zipResult);
// output: H4sIAAAAAAAAAzM0MjYBAKPg45sEAAAA
var unzipResult = pako.ungzip(atob("H4sIAAAAAAAAAzM0MjYBAKPg45sEAAAA"), {to: "string"});
console.log(unzipResult);
// output: 1234

zlib

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const zlib = require('zlib');

function btoa(str) {
return Buffer.from(str).toString('base64');
}

function atob(b64Encoded) {
return Buffer.from(b64Encoded, 'base64');
}

var zipResult = btoa(zlib.deflateSync("1234"));
console.log(zipResult);
// output: eJwzNDI2AQAB+ADL
var unzipResult = zlib.inflateSync(atob("eJwzNDI2AQAB+ADL")).toString();
console.log(unzipResult);
// output: 1234

var zipResult = btoa(zlib.gzipSync(Buffer.from("1234")));
console.log(zipResult);
// output: H4sIAAAAAAAAAzM0MjYBAKPg45sEAAAA
var unzipResult = zlib.gunzipSync(atob("H4sIAAAAAAAAAzM0MjYBAKPg45sEAAAA")).toString();
console.log(unzipResult);
// output: 1234

参考

web 服务的版本号对于恶意的攻击者无疑是有帮助的,因为不同版本号或多或少有其对应的漏洞,一旦被恶意的攻击者发现将对线上服务造成严重危害。而隐藏服务版本号则有助于提升 web 的安全性。

阅读全文 »

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 不同 worker 绑定到不同核上,提高 CPU 缓存命中率,auto 根据 worker 数量自动绑定 CPU。
worker_cpu_affinity auto;

sendfile on;
tcp_nopush on;
tcp_nodelay on;

keepalive_timeout 60;

ssl_session_tickets on;
ssl_session_ticket_key ticket.key;

# 所有 worker 进程之间共享的缓存大小,1兆大约可以存储 4000 个会话,此处可存储 40000 个会话。
ssl_session_cache shared:SSL:10m;
# 会话超时时间
ssl_session_timeout 10m;

listen 80 reuseport backlog=8192; # reuseport linux > 3.9 CentOS >= 7.0

用于加密和解密TLS会话票据的密钥设置,生成 ticket 文件,必须含有80或48个字节的随机数据。

1
openssl rand 80> ticket.key

certbot 自动化脚本生成 Let’s Encrypt 免费证书。

1
2
3
yum install python2-certbot-nginx

certbot --nginx --nginx-server-root=/usr/local/nginx/conf/ -d test.codezm.com

域名 test.codezm.com 必须可访问。CA机构才能颁发证书。https://certbot.eff.org/docs/install.html

Tcp 优化

SYN_RCVD 状态
  • SYN - SYN_RECEIVED QUEUE
    • net.ipv4.tcp_max_syn_backlog=262144 接收 SYN 最大数量,半链接个数。SYN
      • 查看:cat /proc/sys/net/ipv4/tcp_max_syn_backlog
    • net.ipv4.tcp_synack_retries 被动建立连接时,发送 SYN/ACK 的重试次数。SYN+ACK
      • 查看:cat /proc/sys/net/ipv4/tcp_synack_retries
  • ACCEPT - ESTABLISHED QUEUE
    • net.core.somaxconn 系统级最大 backlog 队列长度。
    • nginx 端口限制 backlog 队列长度
      • listen 80 backlog=8192;
    • 如何查看 Accept queue 溢出?
      • netstat -s | grep LISTEN ,返回 SYNS to LISTEN sockets ignored 时。

防止 SYN 攻击,开启 net.ipv4.tcp_syncookies=1 ,在 SYN 队列满时,启用 cookie。

一切皆文件:句柄数的上限

操作系统全局
  • fs.file-max 操作系统可使用的最大句柄数

    1
    sysctl -a | grep file-max
- fs.file-nr 查看当前已分配(正使用)、待重新分配、上限
限制用户
  • /etc/security/limits.conf

    • root soft nofile 65535
    • root hard nofile 65535

    限制 root 用户,软、硬链接个数。

    hard 强制的、真实的链接,soft 软的限制,进程在运行时自动的修改软限制、但无法修改硬的,soft 一定要小于 hard

* - noproc 11000

  • * 代表针对所有用户

  • - 的意思为 softhard 全部限制。

  • nofile 代表最大文件打开数

  • noproc 代表最大进程数

限制进程

Syntax: worker_rlimit_nofile number;

Default: -

Context: main

限制一个 worker 进程最大能打开的文件句柄数。

活动连接数查看
  • ss -n | grep ESTAB | wc -l
Tcp Fast Open - TFO

image-20201230172342579

net.ipv4_tcp_fastopen 需 Client、Server 两端均支持 TFO。

  • 0:关闭
  • 1:作为客户端时可以使用TFO
  • 2:作为服务端时可以使用TFO
  • 3:无论作为客户端还是服务端,都可以使用TFO

Syntax: listen address[:port] [fastopen=number];

Default: listen *:80 | *:8000;

Context: server

fastopen=number 为防止带数据的 SYN 攻击,限制最大长度,指定 TFO 连接队列的最大长度。

worker 进程最大连接数量

包括 Nginx 与上游、下游间的连接。

Syntax: worker_connections numbers;

Default: worker_connections 512;

Context: events

参考