Giter Club home page Giter Club logo

patch's Introduction

Patches

Nginx

nginx_dynamic_tls_records.patch

  • Add Dynamic TLS Record Support.

Require: Nginx 1.25.1

Test pass: 1.25.4

use_openssl_md5_sha1.patch

  • Use the OpenSSL library instead of the Nginx original function.
  • Repack it because "patch unexpectedly ends in middle of line".

Test pass: 1.25.4

Enable_BoringSSL_OCSP.patch

  • For BoringSSL support OCSP stapling.
    • Using "ssl_stapling_file" to support.
    • Only "ssl_stapling_file" with single cert is supported.
    • Auto-rebuild OCSP stapling file with shell and atd(at cron), you can read this article(Maybe you need a translation tool).
    • Thanks @CarterLi.

Test pass: 1.25.3

nginx.patch (Discontinued)

  • Add HTTP2 HPACK Encoding Support.
  • Add Dynamic TLS Record Support.

Require: Nginx 1.25.0 (this version only)

Test pass: 1.25.0

Since Nginx 1.25.1, HPACK encoding will not support because the HTTP/2 server push support has been removed.

nginx_with_quic.patch (Discontinued)

  • Add HTTP3(QUIC) Support.
    • For OCSP stapling, maybe you need this.
  • Add HTTP2 HPACK Encoding Support.
  • Add Dynamic TLS Record Support.

Require: Nginx 1.21.4 or later.

Test pass: 1.23.3 with cloudflare/quiche@c9311a1

Check your modules when build failed.

nginx_for_1.23.4.patch (Deprecated)

  • Add HTTP2 HPACK Encoding Support.
  • Add Dynamic TLS Record Support.

Require: Nginx version below 1.25.0

Test pass: 1.23.4

nginx_with_quic_for_1.19.7_full.patch (Deprecated)

  • Add HTTP3(QUIC) Support.
    • For OCSP stapling, maybe you need this.
  • Add HTTP2 HPACK Encoding Support.
  • Add Dynamic TLS Record Support.

Require: Nginx 1.19.7 or later(below 1.21.4).

Test pass: 1.21.3 with cloudflare/quiche@af1bbc0

nginx_with_quic_for_1.19.6.patch is required to support Nginx versions lower than 1.19.7, cause post_accept_timeout had been removed by Nginx since 1.19.7.

nginx_with_quic_for_1.19.6.patch (Deprecated)

  • Revert nginx_with_quic.patch to support Nginx versions lower than 1.19.7.
  • Patch nginx_with_quic.patch first, then patch this one.

Test pass: 1.19.6 with nginx_with_quic.patch@ec8cac4 & cloudflare/quiche@fca5e9a

nginx_with_spdy.patch (Deprecated)

  • Add SPDY Support.
  • Add HTTP2 HPACK Encoding Support.
  • Add Dynamic TLS Record Support.

Test pass: 1.17.9

nginx_with_spdy_quic.patch (Deprecated)

  • Add SPDY Support.
  • Add HTTP3(QUIC) Support.
  • Add HTTP2 HPACK Encoding Support.
  • Add Dynamic TLS Record Support.

Test pass: 1.17.9 with cloudflare/quiche@9a8b3b

Other

openssl-1.1.1.patch

  • Add TLS 1.3 Support.
  • Add BoringSSL's Equal Preference Support.
  • Add ChaCha20-Poly1305 Draft Version Support.

Test pass: 1.1.1w

ffmpeg-let-rtmp-flv-support-hevc-h265-opus.patch

  • FLV/RTMP Extensions For FFmpeg.
    • Add FLV Encode/Decode with H.265/HEVC & OPUS Codec Support.
    • Add RTMP Stream Push with H.265/HEVC & OPUS Codec Support.
    • Thanks @xia-chu.

Test pass: 4.3.1

dropbox_fs_fix.patch

  • For Dropbox Linux users. This patch could let official python script auto-load libdropbox_fs_fix.so library before start dropboxd.
    • Using Dropbox filesystem fix for Linux Repo and make libdropbox_fs_fix.so.
    • After compiled, copy libdropbox_fs_fix.so to $HOME/.dropbox-dist/libdropbox_fs_fix.so.
    • Download Dropbox official python script, put it with patch file together.
    • Patch, enjoy.

Test pass: 2019.02.14 version

Links

聊聊Nginx 1.25和HTTP/3

Nginx 1.19.4新特性推荐

让Nginx使用BoringSSL时支持OCSP Stapling

博客终止使用TLS 1.0和TLS 1.1协议

小试HTTP3

我的Nginx编译之旅

解决Dropbox Linux客户端因文件系统导致无法同步问题

kn007的个人博客

patch's People

Contributors

kn007 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

patch's Issues

Pass connection RTT from quiche to nginx variable

Any plans to add a $tcpinfo_ analogue in nginx_with_quic.patch?

In my use case I'm passing an RTT value of the each client to the upstream:
nginx.conf

proxy_set_header        X-TCP-RTT              $tcpinfo_rtt;

It looks like quiche has some similar stats:

https://github.com/cloudflare/quiche/blob/92dcc500462ac22bb72e822d3f4e99039d29acfd/src/ffi.rs#L1000-L1034

I am a bit confused of how it can be passed from quiche to nginx variable. Could you help?

https://github.com/nginx/nginx/blob/e56ba23158b8466d108fd4d571bd7d9a88f2a473/src/http/ngx_http_variables.c#L1100-L1148

请问如何启用 hpack?

请问要启用 hpack 的话,只需在 configure 时添加 --with-http_v2_hpack_enc 参数即可,还是需要修改 nginx.conf ?
btw,如果对 SPDY 没有需求的话,patch 之后不添加编译选项是否可以取消对 SPDY 的支持?
THX!

nginx h3 patch not forward post context to upstream

Nginx 1.21.4 build with nginx_with_quic.patch, and I add $request_body into nginx log.

I can see the nginx accept the request body, but upstream request_body is empty.

I can see the protocol is h3 from browser.

Turn on/off ssl_dyn_rec_enable not help.

Remove this fix the bugs:

 listen 443 quic;
add_header alt-svc 'h3=":443"; ma=86400, h3-29=":443"; ma=86400, h3-28=":443"; ma=86400, h3-27=":443"; ma=86400';

quiche with latest boringssl

I had to make some changes to get it compiling with the latest boringssl.

The quiche deps boringssl folder is empty even with doing git submodule --init, I do this instead:

rm -rf quiche/deps
mkdir quiche/deps
cd quiche/deps
git clone https://github.com/google/boringssl.git

nginx_with_quic.patch

+       mkdir -p $OPENSSL/build $OPENSSL/.openssl/lib $OPENSSL/.openssl/include/openssl \\
+       && cd $OPENSSL/build \\
+       && cmake -DCMAKE_C_FLAGS="$OPENSSL_OPT" -DCMAKE_CXX_FLAGS="$OPENSSL_OPT -Wno-stringop-overread" .. \\
+       && \$(MAKE) VERBOSE=1 \\
+       && cd .. \\
+       && cp -r include/openssl/*.h .openssl/include/openssl \\
+       && cp build/ssl/libssl.a build/crypto/libcrypto.a .openssl/lib

when I enable quic, all my php requests error 500, in the logs it says:
[alert] 3924644#3924644: *5 epoll_ctl(1, 14) failed (17: File exists)

patch的时候有报错

Nginx1.15.8
使用的patch版本是commit d6bd9f7,看更新说明支持1.15.8。

root@host:~/src/nginx-1.15.8# patch -p1 < ../patch/nginx.patch
patching file auto/modules
patching file auto/options
patching file src/core/ngx_connection.h
patching file src/core/ngx_murmurhash.c
patching file src/core/ngx_murmurhash.h
patching file src/event/ngx_event_openssl.c
Hunk #1 succeeded at 1272 (offset 33 lines).
Hunk #2 succeeded at 2125 (offset 318 lines).
Hunk #3 succeeded at 2267 (offset 324 lines).
patching file src/event/ngx_event_openssl.h
Hunk #3 succeeded at 117 (offset 6 lines).
1 out of 3 hunks FAILED -- saving rejects to file src/event/ngx_event_openssl.h.rej

EDIT:我的问题,抱歉

Feature: Use SSL_OP_PRIORITIZE_CHACHA when supported ( openssl 1.1.1 )

https://github.com/openssl/openssl/blob/7731e619fba2f9ea1e888bf906289be37c52e6ac/include/openssl/ssl.h#L358

commit 403a3e2323be2109fdda00564953aabdd164bb79
Author: 李通洲 <[email protected]>
Date:   Thu Apr 5 15:50:51 2018 +0800

    SSL_OP_PRIORITIZE_CHACHA

diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
index 88a6dbe..f79c394 100644
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -330,6 +330,10 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data)
     }
 #endif
 
+#ifdef SSL_OP_PRIORITIZE_CHACHA
+    SSL_CTX_set_options(ssl->ctx, SSL_OP_PRIORITIZE_CHACHA);
+#endif
+
 #ifdef SSL_OP_NO_COMPRESSION
     SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_COMPRESSION);
 #endif

Tested with nginx 1.13.11

$ ./testssl.sh -c test.eoitek.net

###########################################################
    testssl.sh       2.9dev from https://testssl.sh/dev/
    (6b8f6f8 2018-03-28 19:46:55 -- )

      This program is free software. Distribution and
             modification under GPLv2 permitted.
      USAGE w/o ANY WARRANTY. USE IT AT YOUR OWN RISK!

       Please file bugs @ https://testssl.sh/bugs/

###########################################################

 Using "OpenSSL 1.0.2-chacha (1.0.2i-dev)" [~183 ciphers]
 on litongzhoudeMacBook-Pro:./bin/openssl.Darwin.x86_64
 (built: "Sep  7 19:34:54 2016", platform: "darwin64-x86_64-cc")


 Start 2018-04-05 16:19:57        -->> 127.0.0.1:443 (test.eoitek.net) <<--

 A record via            /etc/hosts
 rDNS (127.0.0.1):       --
 Service detected:       HTTP


 Running client simulations via sockets

 Android 2.3.7                No connection
 Android 4.1.1                TLSv1.0 ECDHE-ECDSA-AES128-SHA, 256 bit ECDH (P-256)
 Android 4.3                  TLSv1.0 ECDHE-ECDSA-AES128-SHA, 256 bit ECDH (P-256)
 Android 4.4.2                TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
 Android 5.0.0                TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
 Android 6.0                  TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
 Android 7.0                  TLSv1.2 ECDHE-ECDSA-CHACHA20-POLY1305, 253 bit ECDH (X25519)
 Chrome 51 Win 7              TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 253 bit ECDH (X25519)
 Chrome 57 Win 7              TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 253 bit ECDH (X25519)
 Firefox 49 Win 7             TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
 Firefox 53 Win 7             TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 253 bit ECDH (X25519)
 IE 6 XP                      No connection
 IE 7 Vista                   TLSv1.0 ECDHE-ECDSA-AES128-SHA, 256 bit ECDH (P-256)
 IE 8 XP                      No connection
 IE 8 Win 7                   TLSv1.0 ECDHE-ECDSA-AES128-SHA, 256 bit ECDH (P-256)
 IE 11 Win 7                  TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
 IE 11 Win 8.1                TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
 IE 11 Win Phone 8.1 Update   TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
 IE 11 Win 10                 TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
 Edge 13 Win 10               TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
 Edge 13 Win Phone 10         TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
 Opera 17 Win 7               TLSv1.2 ECDHE-ECDSA-AES128-SHA256, 256 bit ECDH (P-256)
 Safari 5.1.9 OS X 10.6.8     TLSv1.0 ECDHE-ECDSA-AES128-SHA, 256 bit ECDH (P-256)
 Safari 7 iOS 7.1             TLSv1.2 ECDHE-ECDSA-AES128-SHA256, 256 bit ECDH (P-256)
 Safari 9 OS X 10.11          TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
 Safari 10 OS X 10.12         TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
 Apple ATS 9 iOS 9            TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
 Tor 17.0.9 Win 7             TLSv1.0 ECDHE-ECDSA-AES128-SHA, 256 bit ECDH (P-256)
 Java 6u45                    No connection
 Java 7u25                    TLSv1.0 ECDHE-ECDSA-AES128-SHA, 256 bit ECDH (P-256)
 Java 8u31                    TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
 OpenSSL 1.0.1l               TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
 OpenSSL 1.0.2e               TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)

 Done 2018-04-05 16:20:46 [0053s] -->> 127.0.0.1:443 (test.eoitek.net) <<--

openssl 1.1.1

did you how to patch openssl 1.1.1 with nginx for supporting all drafts(23,..) no only last(28) ?

Patch conflict `nginx_with_quic.patch` for 1.21.4

Mostly because Nginx mainline removes NPN support.

patching file auto/lib/conf
patching file auto/lib/make
patching file auto/lib/openssl/make
patching file auto/lib/quiche/conf
patching file auto/lib/quiche/make
patching file auto/make
patching file auto/modules
Hunk #1 succeeded at 118 (offset -1 lines).
Hunk #2 succeeded at 151 (offset -1 lines).
Hunk #3 succeeded at 213 (offset -1 lines).
Hunk #4 succeeded at 435 (offset -1 lines).
Hunk #5 succeeded at 1301 (offset -1 lines).
patching file auto/options
patching file src/core/ngx_connection.h
patching file src/core/ngx_core.h
patching file src/core/ngx_murmurhash.c
patching file src/core/ngx_murmurhash.h
patching file src/event/ngx_event_openssl.c
Hunk #1 succeeded at 1626 (offset 2 lines).
Hunk #2 succeeded at 2593 (offset 23 lines).
Hunk #3 succeeded at 2767 (offset 55 lines).
patching file src/event/ngx_event_openssl.h
Hunk #2 succeeded at 128 (offset 1 line).
Hunk #3 succeeded at 141 (offset 1 line).
patching file src/event/ngx_event_quic.c
patching file src/event/ngx_event_quic.h
patching file src/event/ngx_event_udp.c
patching file src/http/modules/ngx_http_ssl_module.c
Hunk #1 succeeded at 296 (offset -5 lines).
Hunk #2 succeeded at 456 (offset -2 lines).
Hunk #3 succeeded at 473 with fuzz 2 (offset -2 lines).
Hunk #4 succeeded at 483 with fuzz 2 (offset -4 lines).
Hunk #5 succeeded at 639 (offset -42 lines).
Hunk #6 succeeded at 719 (offset -42 lines).
Hunk #7 succeeded at 959 (offset -47 lines).
patching file src/http/modules/ngx_http_ssl_module.h
patching file src/http/ngx_http.c
Hunk #7 succeeded at 1737 (offset -1 lines).
Hunk #8 succeeded at 1824 (offset -1 lines).
Hunk #9 succeeded at 1863 (offset -1 lines).
Hunk #10 succeeded at 1931 (offset -1 lines).
patching file src/http/ngx_http_core_module.c
patching file src/http/ngx_http_core_module.h
patching file src/http/ngx_http.h
patching file src/http/ngx_http_request_body.c
patching file src/http/ngx_http_request.c
Hunk #3 FAILED at 823.
Hunk #4 succeeded at 832 with fuzz 2 (offset -1 lines).
Hunk #5 succeeded at 836 with fuzz 2 (offset -12 lines).
Hunk #6 succeeded at 1083 (offset -12 lines).
Hunk #7 succeeded at 2836 (offset -12 lines).
Hunk #8 succeeded at 3057 (offset -12 lines).
Hunk #9 succeeded at 3762 (offset -12 lines).
Hunk #10 succeeded at 3891 (offset -12 lines).
1 out of 10 hunks FAILED -- saving rejects to file src/http/ngx_http_request.c.rej
patching file src/http/ngx_http_request.h
patching file src/http/ngx_http_upstream.c
patching file src/http/v2/ngx_http_v2.c
patching file src/http/v2/ngx_http_v2_encode.c
patching file src/http/v2/ngx_http_v2_filter_module.c
patching file src/http/v2/ngx_http_v2.h
Hunk #1 succeeded at 51 (offset -1 lines).
Hunk #2 succeeded at 122 (offset -1 lines).
Hunk #3 succeeded at 183 (offset -1 lines).
Hunk #4 succeeded at 214 (offset -1 lines).
Hunk #5 succeeded at 262 (offset -1 lines).
Hunk #6 succeeded at 476 (offset -1 lines).
patching file src/http/v2/ngx_http_v2_table.c
patching file src/http/v3/ngx_http_v3.c
patching file src/http/v3/ngx_http_v3_filter_module.c
patching file src/http/v3/ngx_http_v3.h
patching file src/http/v3/ngx_http_v3_module.c
patching file src/http/v3/ngx_http_v3_module.h
patching file src/os/unix/ngx_udp_sendmsg_chain.c

Test pass: 1.21.4 with cloudflare/quiche@af1bbc0

Did you really test it?

配合 quiche 编译 Nginx 1.19.10 时出错

OS: Alpine 3.12

内核: Linux 4.4.0-1060-aws x86_64

GCC: gcc version: 9.3.0 (Alpine 9.3.0)

Nginx 版本: 1.19.10

quiche 版本: 直接 clone 了这个 repo 到 /tmp/quiche/ 目录,然后回滚到 d8bb8e36d5c549c2bc8b87525737899abd061daf 这个commit (大佬 README 所写的测试时的 commit)

Nginx 的部分编译配置:

--with-openssl=/tmp/quiche/deps/boringssl
--with-quiche=/tmp/quiche
--with-cc-opt="-g -Ofast -fPIE -pie -march=native -fstack-protector-strong -D_FORTIFY_SOURCE=2 -m64 -O3 -fno-strict-aliasing -DTCP_FASTOPEN=23 -D_GLIBCXX_USE_CXX11_ABI=0 -ffast-math -flto -fuse-linker-plugin --param=ssp-buffer-size=4 -Wformat -Wno-deprecated-declarations -DNGX_LUA_ABORT_AT_PANIC"
--with-ld-opt="-lapr-1 -laprutil-1 -licudata -licuuc -lrt -lpng -lturbojpeg -ljpeg -Wl,-Bsymbolic-functions -fPIE -pie -Wl,-z,relro -Wl,-z,now -Wl,-rpath,/usr/local/lib"

编译时的部分 log(出错前后):

`rustc --crate-name build_script_build --edition=2018 src/build.rs --error-format=json --json=diagnostic-rendered-ansi --crate-type bin --emit=dep-info,link -C debuginfo=2 --cfg 'feature="ffi"' -C metadata=f9071125c3d69bbb -C extra-filename=-f9071125c3d69bbb --out-dir /tmp/quiche/target/debug/build/quiche-f9071125c3d69bbb -C incremental=/tmp/quiche/target/debug/incremental -L dependency=/tmp/quiche/target/debug/deps --extern cmake=/tmp/quiche/target/debug/deps/libcmake-68aa8b03865be436.rlib`

 Running `/tmp/quiche/target/debug/build/ring-e390dddfe04ab00b/build-script-build`

 Running `/tmp/quiche/target/debug/build/quiche-f9071125c3d69bbb/build-script-build`

 Running `rustc --crate-name ring --edition=2018 /root/.cargo/registry/src/github.com-1ecc6299db9ec823/ring-0.16.20/src/lib.rs --error-format=json --json=diagnostic-rendered-ansi --crate-type lib --emit=dep-info,metadata,link -C debuginfo=2 --cfg 'feature="alloc"' --cfg 'feature="default"' --cfg 'feature="dev_urandom_fallback"' --cfg 'feature="once_cell"' -C metadata=28f9ff3d173ba057 -C extra-filename=-28f9ff3d173ba057 --out-dir /tmp/quiche/target/debug/deps -L dependency=/tmp/quiche/target/debug/deps --extern libc=/tmp/quiche/target/debug/deps/liblibc-cfa004638bb84817.rmeta --extern once_cell=/tmp/quiche/target/debug/deps/libonce_cell-bf7e2012cdbe5b0f.rmeta --extern spin=/tmp/quiche/target/debug/deps/libspin-69e46ebdf28e1a75.rmeta --extern untrusted=/tmp/quiche/target/debug/deps/libuntrusted-9605fa52722215b8.rmeta --cap-lints allow -L native=/tmp/quiche/target/debug/build/ring-741b744bfaca4f3a/out -l static=ring-core -l static=ring-test`

 Running `rustc --crate-name quiche --edition=2018 src/lib.rs --error-format=json --json=diagnostic-rendered-ansi --crate-type lib --crate-type staticlib --crate-type cdylib --emit=dep-info,link -C debuginfo=2 --cfg 'feature="ffi"' -C metadata=46e4b4bd1a86cc9d --out-dir /tmp/quiche/target/debug/deps -C incremental=/tmp/quiche/target/debug/incremental -L dependency=/tmp/quiche/target/debug/deps --extern lazy_static=/tmp/quiche/target/debug/deps/liblazy_static-685a72be080b70c1.rlib --extern libc=/tmp/quiche/target/debug/deps/liblibc-cfa004638bb84817.rlib --extern libm=/tmp/quiche/target/debug/deps/liblibm-c6ab75713beb40d2.rlib --extern log=/tmp/quiche/target/debug/deps/liblog-668c510e02672168.rlib --extern ring=/tmp/quiche/target/debug/deps/libring-28f9ff3d173ba057.rlib -L native=/tmp/quiche/target/debug/build/ring-741b744bfaca4f3a/out`

error[E0658]: use of unstable library feature 'slice_fill'
--> src/lib.rs:2132:39
|
2132 | out[done..done + pad_len].fill(0);
| ^^^^
|
= note: see issue #70758 <https://github.com/rust-lang/rust/issues/70758> for more information

error: aborting due to previous error
For more information about this error, try `rustc --explain E0658`.

error: could not compile `quiche`.
Caused by:
process didn't exit successfully: `rustc --crate-name quiche --edition=2018 src/lib.rs --error-format=json --json=diagnostic-rendered-ansi --crate-type lib --crate-type staticlib --crate-type cdylib --emit=dep-info,link -C debuginfo=2 --cfg 'feature="ffi"' -C metadata=46e4b4bd1a86cc9d --out-dir /tmp/quiche/target/debug/deps -C incremental=/tmp/quiche/target/debug/incremental -L dependency=/tmp/quiche/target/debug/deps --extern lazy_static=/tmp/quiche/target/debug/deps/liblazy_static-685a72be080b70c1.rlib --extern libc=/tmp/quiche/target/debug/deps/liblibc-cfa004638bb84817.rlib --extern libm=/tmp/quiche/target/debug/deps/liblibm-c6ab75713beb40d2.rlib --extern log=/tmp/quiche/target/debug/deps/liblog-668c510e02672168.rlib --extern ring=/tmp/quiche/target/debug/deps/libring-28f9ff3d173ba057.rlib -L native=/tmp/quiche/target/debug/build/ring-741b744bfaca4f3a/out` (exit code: 1)

make[1]: *** [objs/Makefile:2441: /tmp/quiche/target/debug/libquiche.a] Error 101

make[1]: Leaving directory '/tmp/nginx-1.19.10'
make: *** [Makefile:10: build] Error 2

看着像是 quiche 自己的错误?但是看大佬好像编译通过了,所以想请教一下大佬编译时的一些配置什么的

Edited:

好像是 Rust 的错误?

里面提到了 Rust 1.50 版本: rust-lang/rust#70758 (comment)

看了下 Alpine 3.12 的 Rust 版本好像是 1.44.0-r0,先试一下用 Alpine Edge 编译看看

Patch that enables OCSP stapling for nginx with **BoringSSL**

For people who like 折腾
Note only "ssl_stapling_file" with single cert is supported. Use it as your own risk.

From 4be7f3188f18c64ef3de6cc35331220195de2b94 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= <[email protected]>
Date: Sat, 19 May 2018 22:08:47 +0800
Subject: [PATCH] Support OSCP stapling on BoringSSL

---
 src/event/ngx_event_openssl_stapling.c | 42 ++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/src/event/ngx_event_openssl_stapling.c b/src/event/ngx_event_openssl_stapling.c
index 0bea5e7..334f1c2 100644
--- a/src/event/ngx_event_openssl_stapling.c
+++ b/src/event/ngx_event_openssl_stapling.c
@@ -1874,8 +1874,50 @@ ngx_int_t
 ngx_ssl_stapling(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file,
     ngx_str_t *responder, ngx_uint_t verify)
 {
+#ifdef BORINGSSL_MAKE_DELETER
+    ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
+                  "using boringssl, currently only \"ssl_stapling_file\" is supported. use it as your own risk");
+
+    BIO            *bio;
+    int             len;
+    u_char          buf[1024];
+
+    if (ngx_conf_full_name(cf->cycle, file, 1) != NGX_OK) {
+        return NGX_ERROR;
+    }
+
+    bio = BIO_new_file((char *) file->data, "r");
+    if (bio == NULL) {
+        ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+                      "BIO_new_file(\"%s\") failed", file->data);
+        return NGX_ERROR;
+    }
+
+    len = BIO_read(bio, buf, sizeof(buf) / sizeof(u_char));
+    BIO_free(bio);
+    bio = NULL;
+
+    if (len <= 0) {
+        ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+                      "Read OCSP response file \"%s\" failed: %d", file->data, len);
+        return NGX_ERROR;
+    }
+
+    if (len >= 1000) {
+        ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+                      "Unexpected OCSP response file length: %d", len);
+        return NGX_ERROR;
+    }
+
+    if (!SSL_CTX_set_ocsp_response(ssl->ctx, buf, len)) {
+        ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+                      "SSL_CTX_set_ocsp_response(ssl->ctx, buf, %d) failed", len);
+        return NGX_ERROR;
+    }
+#else
     ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
                   "\"ssl_stapling\" ignored, not supported");
+#endif
 
     return NGX_OK;
 }
-- 
2.17.0

Tested on Nginx/1.14.0, BoringSSL/master with nginx.patch
Be sure to apply this patch to enable TLS13 support

$ ./testssl.sh test.eoitek.net

###########################################################
    testssl.sh       3.0beta from https://testssl.sh/dev/
    (e68b1ce 2018-05-15 17:54:09 -- )

      This program is free software. Distribution and
             modification under GPLv2 permitted.
      USAGE w/o ANY WARRANTY. USE IT AT YOUR OWN RISK!

       Please file bugs @ https://testssl.sh/bugs/

###########################################################

 Using "OpenSSL 1.0.2-chacha (1.0.2i-dev)" [~183 ciphers]
 on litongzhoudeMacBook-Pro:./bin/openssl.Darwin.x86_64
 (built: "Sep  7 19:34:54 2016", platform: "darwin64-x86_64-cc")


 Start 2018-05-19 22:14:47        -->> 127.0.0.1:443 (test.eoitek.net) <<--

 A record via            /etc/hosts
 rDNS (127.0.0.1):       localhost.
 Service detected:       HTTP


 Testing protocols via sockets except NPN+ALPN

 SSLv2      not offered (OK)
 SSLv3      not offered (OK)
 TLS 1      offered
 TLS 1.1    offered
 TLS 1.2    offered (OK)
 TLS 1.3    offered (OK): draft 28, draft 23
 NPN/SPDY   h2, spdy/3.1, http/1.1 (advertised)
 ALPN/HTTP2 h2, spdy/3.1, http/1.1 (offered)

 Testing cipher categories

 NULL ciphers (no encryption)                  not offered (OK)
 Anonymous NULL Ciphers (no authentication)    not offered (OK)
 Export ciphers (w/o ADH+NULL)                 not offered (OK)
 LOW: 64 Bit + DES encryption (w/o export)     not offered (OK)
 Weak 128 Bit ciphers (SEED, IDEA, RC[2,4])    not offered (OK)
 Triple DES Ciphers (Medium)                   not offered (OK)
 High encryption (AES+Camellia, no AEAD)       offered (OK)
 Strong encryption (AEAD ciphers)              offered (OK)


 Testing robust (perfect) forward secrecy, (P)FS -- omitting Null Authentication/Encryption, 3DES, RC4

 PFS is offered (OK)          TLS_AES_256_GCM_SHA384 TLS_CHACHA20_POLY1305_SHA256 ECDHE-ECDSA-CHACHA20-POLY1305
                              TLS_AES_128_GCM_SHA256 ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-ECDSA-AES128-SHA
 Elliptic curves offered:     prime256v1 secp384r1 X25519


 Testing server preferences

 Has server cipher order?     yes (OK)
 Negotiated protocol          TLSv1.3
 Negotiated cipher            TLS_AES_256_GCM_SHA384, 253 bit ECDH (X25519)
 Cipher order
    TLSv1:     ECDHE-ECDSA-AES128-SHA
    TLSv1.1:   ECDHE-ECDSA-AES128-SHA
    TLSv1.2:   ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-ECDSA-AES128-SHA ECDHE-ECDSA-CHACHA20-POLY1305
    TLSv1.3:   TLS_AES_256_GCM_SHA384 TLS_CHACHA20_POLY1305_SHA256 TLS_AES_128_GCM_SHA256

./testssl.sh:行6341: 警告:command substitution: ignored null byte in input
./testssl.sh:行6341: 警告:command substitution: ignored null byte in input

 Testing server defaults (Server Hello)

 TLS extensions (standard)    "renegotiation info/#65281" "session ticket/#35" "status request/#5"
                              "next protocol/#13172" "EC point formats/#11" "key share/#51" "supported versions/#43"
                              "extended master secret/#23" "application layer protocol negotiation/#16"
 Session Ticket RFC 5077 hint 300 seconds, session tickets keys seems to be rotated < daily
 SSL Session ID support       yes
 Session Resumption           Tickets: yes, ID: no
 TLS clock skew               -1 sec from localtime
 Signature Algorithm          SHA256 with RSA
 Server key size              EC 256 bits
 Server key usage             Digital Signature
 Server extended key usage    TLS Web Server Authentication, TLS Web Client Authentication
 Serial / Fingerprints        03A2070FFC8B2171C43AB210C422439C026A / SHA1 13513B51E0076C1C166D5280BB66BCA8D1EA368D
                              SHA256 5E354315F3DB4B9E887F54D32374241124F1BE2F46441322D0412ADC63B2F10C
 Common Name (CN)             *.eoitek.net
 subjectAltName (SAN)         *.eoitek.net
 Issuer                       Let's Encrypt Authority X3 (Let's Encrypt from US)
 Trust (hostname)             Ok via SAN wildcard and CN wildcard (same w/o SNI)
 Chain of trust               Ok
 EV cert (experimental)       no
 Certificate Validity (UTC)   45 >= 30 days (2018-04-05 15:02 --> 2018-07-04 15:02)
 # of certificates provided   2
 Certificate Revocation List  --
 OCSP URI                     http://ocsp.int-x3.letsencrypt.org
 OCSP stapling                offered
 OCSP must staple extension   --
 DNS CAA RR (experimental)    available - please check for match with "Issuer" above
                              iodef=mailto:[email protected], issue=letsencrypt.org
 Certificate Transparency     yes (certificate extension)


 Testing HTTP header response @ "/"

 HTTP Status Code             403 Forbidden
 HTTP clock skew              0 sec from localtime
 Strict Transport Security    not offered
 Public Key Pinning           --
 Server banner                nginx/1.14.0
 Application banner           --
 Cookie(s)                    (none issued at "/") -- maybe better try target URL of 30x
 Security headers             --
 Reverse Proxy banner         --


 Testing vulnerabilities

 Heartbleed (CVE-2014-0160)                not vulnerable (OK), no heartbeat extension
 CCS (CVE-2014-0224)                       not vulnerable (OK)
 Ticketbleed (CVE-2016-9244), experiment.  not vulnerable (OK)
 ROBOT                                     Server does not support any cipher suites that use RSA key transport
 Secure Renegotiation (CVE-2009-3555)      not vulnerable (OK)
 Secure Client-Initiated Renegotiation     not vulnerable (OK)
 CRIME, TLS (CVE-2012-4929)                not vulnerable (OK)
 BREACH (CVE-2013-3587)                    potentially NOT ok, uses gzip HTTP compression. - only supplied "/" tested
                                           Can be ignored for static pages or if no secrets in the page
 POODLE, SSL (CVE-2014-3566)               not vulnerable (OK)
 TLS_FALLBACK_SCSV (RFC 7507)              Downgrade attack prevention supported (OK)
 SWEET32 (CVE-2016-2183, CVE-2016-6329)    not vulnerable (OK)
 FREAK (CVE-2015-0204)                     not vulnerable (OK)
 DROWN (CVE-2016-0800, CVE-2016-0703)      not vulnerable on this host and port (OK)
                                           no RSA certificate, thus certificate can't be used with SSLv2 elsewhere
 LOGJAM (CVE-2015-4000), experimental      not vulnerable (OK): no DH EXPORT ciphers, no DH key detected
 BEAST (CVE-2011-3389)                     TLS1: ECDHE-ECDSA-AES128-SHA
                                           VULNERABLE -- but also supports higher protocols  TLSv1.1 TLSv1.2 (likely mitigated)
 LUCKY13 (CVE-2013-0169), experimental     potentially VULNERABLE, uses cipher block chaining (CBC) ciphers with TLS. Check patches
 RC4 (CVE-2013-2566, CVE-2015-2808)        no RC4 ciphers detected (OK)


 Testing 364 ciphers via OpenSSL plus sockets against the server, ordered by encryption strength

Hexcode  Cipher Suite Name (OpenSSL)       KeyExch.   Encryption  Bits     Cipher Suite Name (RFC)
-----------------------------------------------------------------------------------------------------------------------------
 x1302   TLS_AES_256_GCM_SHA384            ECDH 253   AESGCM      256      TLS_AES_256_GCM_SHA384
 x1303   TLS_CHACHA20_POLY1305_SHA256      ECDH 253   ChaCha20    256      TLS_CHACHA20_POLY1305_SHA256
 xcca9   ECDHE-ECDSA-CHACHA20-POLY1305     ECDH 253   ChaCha20    256      TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
 x1301   TLS_AES_128_GCM_SHA256            ECDH 253   AESGCM      128      TLS_AES_128_GCM_SHA256
 xc02b   ECDHE-ECDSA-AES128-GCM-SHA256     ECDH 256   AESGCM      128      TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
 xc009   ECDHE-ECDSA-AES128-SHA            ECDH 256   AES         128      TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA


 Running client simulations via sockets

 Android 4.2.2                TLSv1.0 ECDHE-ECDSA-AES128-SHA, 256 bit ECDH (P-256)
 Android 4.4.2                TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
 Android 5.0.0                TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
 Android 6.0                  TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
 Android 7.0                  TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 253 bit ECDH (X25519)
 Chrome 57 Win 7              TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 253 bit ECDH (X25519)
 Chrome 65 Win 7              TLSv1.3 TLS_AES_128_GCM_SHA256, 253 bit ECDH (X25519)
 Firefox 53 Win 7             TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 253 bit ECDH (X25519)
 Firefox 59 Win 7             TLSv1.3 TLS_AES_128_GCM_SHA256, 253 bit ECDH (X25519)
 IE 6 XP                      No connection
 IE 7 Vista                   TLSv1.0 ECDHE-ECDSA-AES128-SHA, 256 bit ECDH (P-256)
 IE 8 Win 7                   TLSv1.0 ECDHE-ECDSA-AES128-SHA, 256 bit ECDH (P-256)
 IE 8 XP                      No connection
 IE 11 Win 7                  TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
 IE 11 Win 8.1                TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
 IE 11 Win Phone 8.1          TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
 IE 11 Win 10                 TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
 Edge 13 Win 10               TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
 Edge 13 Win Phone 10         TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
 Edge 15 Win 10               TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 253 bit ECDH (X25519)
 Opera 17 Win 7               TLSv1.2 ECDHE-ECDSA-AES128-SHA, 256 bit ECDH (P-256)
 Safari 9 iOS 9               TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
 Safari 9 OS X 10.11          TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
 Safari 10 OS X 10.12         TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
 Apple ATS 9 iOS 9            TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
 Tor 17.0.9 Win 7             TLSv1.0 ECDHE-ECDSA-AES128-SHA, 256 bit ECDH (P-256)
 Java 6u45                    No connection
 Java 7u25                    TLSv1.0 ECDHE-ECDSA-AES128-SHA, 256 bit ECDH (P-256)
 Java 8u161                   TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
 Java 9.0.4                   TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
 OpenSSL 1.0.1l               TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
 OpenSSL 1.0.2e               TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)

 Done 2018-05-19 22:18:12 [0229s] -->> 127.0.0.1:443 (test.eoitek.net) <<--

error: variable 'data' may be uninitialized when used here

src/http/ngx_http_request.c:855:29: error: variable 'data' may be uninitialized when used here [-Werror,-Wconditional-uninitialized]
            if (len == 2 && data[0] == 'h' && data[1] == '2') {
                            ^~~~
src/http/ngx_http_request.c:831:37: note: initialize the variable 'data' to silence this warning
        const unsigned char    *data;
                                    ^
                                     = NULL
src/http/ngx_http_request.c:855:17: error: variable 'len' may be uninitialized when used here [-Werror,-Wconditional-uninitialized]
            if (len == 2 && data[0] == 'h' && data[1] == '2') {
                ^~~
src/http/ngx_http_request.c:830:36: note: initialize the variable 'len' to silence this warning
        unsigned int            len;

error "epoll_ctl(1, 11) failed (17: File exists)" when post method (500 status ) in patch/nginx_with_quic.patch

nginx/1.24.0 + quiche-b3c73e3d + patch/nginx_with_quic.patch

When client using HTTP3+post method , nginx will return 500 status and errors in logs:

st: "api.xxxxxx.com", referrer: "https://m.xxxxxx.com/"
2023/04/27 20:04:43 [alert] 1769489#1769489: *976258 epoll_ctl(1, 11) failed (17: File exists), client: 60.225.136.177, server: api.xxxxxx.com, request: "POST /mall/v1/trace/spmTrace HTTP/3", host: "api.xxxxxx.com", referrer: "https://m.xxxxxx.com/"
2023/04/27 20:04:43 [alert] 1769489#1769489: *976258 epoll_ctl(1, 11) failed (17: File exists), client: 60.225.136.177, server: api.xxxxxx.com, request: "POST /mall/v1/trace/spmTrace HTTP/3", host: "api.xxxxxx.com", referrer: "https://m.xxxxxx.com/"
2023/04/27 20:04:43 [alert] 1769489#1769489: *976258 epoll_ctl(1, 11) failed (17: File exists), client: 60.225.136.177, server: api.xxxxxx.com, request: "POST /mall/v1/trace/ubrTrace HTTP/3", host: "api.xxxxxx.com", referrer: "https://m.xxxxxx.com/"
2023/04/27 20:04:43 [alert] 1769489#1769489: *976258 epoll_ctl(1, 11) failed (17: File exists), client: 60.225.136.177, server: api.xxxxxx.com, request: "POST /mall/v1/trace/spmTrace HTTP/3", host: "api.xxxxxx.com", referrer: "https://m.xxxxxx.com/"
2023/04/27 20:04:43 [alert] 1769489#1769489: *976258 epoll_ctl(1, 11) failed (17: File exists), client: 60.225.136.177, server: api.xxxxxx.com, request: "POST /mall/v1/trace/spmTrace HTTP/3", host: "api.xxxxxx.com", referrer: "https://m.xxxxxx.com/"
2023/04/27 20:04:44 [alert] 1769489#1769489: *976258 epoll_ctl(1, 11) failed (17: File exists), client: 60.225.136.177, server: api.xxxxxx.com, request: "POST /mall/v1/trace/ubrTrace HTTP/3", host: "api.xxxxxx.com", referrer: "https://m.xxxxxx.com/"
2023/04/27 20:04:44 [alert] 1769489#1769489: *976258 epoll_ctl(1, 11) failed (17: File exists), client: 60.225.136.177, server: api.xxxxxx.com, request: "POST /mall/v1/trace/spmTrace HTTP/3", host: "api.xxxxxx.com", referrer: "https://m.xxxxxx.com/"
2023/04/27 20:04:44 [alert] 1769489#1769489: *976258 epoll_ctl(1, 11) failed (17: File exists), client: 60.225.136.177, server: api.xxxxxx.com, request: "POST /mall/v1/trace/spmTrace HTTP/3", host: "api.xxxxxx.com", referrer: "https://m.xxxxxx.com/"
2023/04/27 20:04:44 [alert] 1769489#1769489: *976258 epoll_ctl(1, 11) failed (17: File exists), client: 60.225.136.177, server: api.xxxxxx.com, request: "POST /mall/v1/trace/spmTrace HTTP/3", host: "api.xxxxxx.com", referrer: "https://m.xxxxxx.com/"
2023/04/27 20:04:45 [alert] 1769489#1769489: *976258 epoll_ctl(1, 11) failed (17: File exists), client: 60.225.136.177, server: api.xxxxxx.com, request: "POST /mall/v1/trace/ubrTrace HTTP/3", host: "api.xxxxxx.com", referrer: "https://m.xxxxxx.com/"
2023/04/27 20:04:45 [alert] 1769489#1769489: *976258 epoll_ctl(1, 11) failed (17: File exists), client: 60.225.136.177, server: api.xxxxxx.com, request: "POST /mall/v1/trace/spmTrace HTTP/3", host: "api.xxxxxx.com", referrer: "https://m.xxxxxx.com/"
2023/04/27 20:04:45 [alert] 1769489#1769489: *976258 epoll_ctl(1, 11) failed (17: File exists), client: 60.225.136.177, server: api.xxxxxx.com, request: "POST /mall/v1/trace/spmT

The quiche nginx offical path is good , not having this issue .

I have found some related this issue :https://giters.com/cloudflare/quiche/issues/640

nginx.patch是否支持Tengine?

今天我用这个补丁给tengine 2.3.2来打,会出现失败的情况
tengine 的nginx内核是1.17.3
我单独直接给nginx 1.17.3打补丁是OK的

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.