├── .github └── workflows │ ├── build.yml │ └── test.yml ├── Dockerfile ├── LICENSE ├── README.md ├── SECURITY.md ├── action.yml ├── build.sh ├── hash ├── minor └── patch /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | on: 3 | schedule: 4 | - cron: "0 0 * * *" 5 | push: 6 | branches: [main] 7 | paths: 8 | - "**.sh" 9 | - Dockerfile 10 | workflow_dispatch: 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | name: build 15 | steps: 16 | - name: Checkout 17 | uses: actions/checkout@v4 18 | - name: Build 19 | uses: ./ 20 | - name: Upload 21 | uses: actions/upload-artifact@v4 22 | with: 23 | name: v8.${{ env.minor }}.${{ env.patch }} 24 | path: /home/runner/work/_temp/_github_home/nginx.deb 25 | - name: Update 26 | if: ${{ env.change }} 27 | uses: stefanzweifel/git-auto-commit-action@v5 28 | with: 29 | commit_message: Update hash and version 30 | - name: Release 31 | if: ${{ env.change }} 32 | uses: softprops/action-gh-release@v1 33 | with: 34 | files: /home/runner/work/_temp/_github_home/nginx.deb 35 | body: "SHA256: ${{ env.hash }}" 36 | tag_name: v8.${{ env.minor }}.${{ env.patch }} 37 | generate_release_notes: false 38 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: test 2 | on: 3 | push: 4 | branches-ignore: [main] 5 | paths: 6 | - "**.sh" 7 | - Dockerfile 8 | workflow_dispatch: 9 | jobs: 10 | test: 11 | runs-on: ubuntu-latest 12 | name: test 13 | steps: 14 | - name: Checkout 15 | uses: actions/checkout@v4 16 | - name: Build 17 | uses: ./ 18 | - name: Upload 19 | uses: actions/upload-artifact@v4 20 | with: 21 | name: v8.${{ env.minor }}.${{ env.patch }} 22 | path: /home/runner/work/_temp/_github_home/nginx.deb 23 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:bookworm 2 | COPY build.sh /build.sh 3 | ENTRYPOINT ["bash", "/build.sh"] 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Xuechen Xu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # nginx-http3 2 | 3 | ## Distribution switch notice 4 | 5 | According to [Debian Wiki](https://wiki.debian.org/DebianReleases), Debian bullseye will reach its end-of-life date in July 2024. Therefore, the project will switch to Debian bookworm as the packaging environment in June 2024. 6 | 7 | **Update:** already switched on June 25th. 8 | 9 | ## Table of Contents 10 | 11 | - [Features](#features) 12 | - [Usage](#usage) 13 | - [Removed modules](#removed-modules) 14 | - [Add modules back](#add-modules-back) 15 | - [Use in another distribution](#use-in-another-distribution) 16 | - [Recommended NGINX config](#recommended-nginx-config) 17 | 18 | ## Features 19 | 20 | - Based on latest [NGINX](https://hg.nginx.org/nginx) mainline version 21 | - HTTP/3 and QUIC support, powered by [quictls](https://github.com/quictls/openssl) 22 | - Brotli support, powered by [ngx_brotli](https://github.com/google/ngx_brotli) 23 | - GeoIP2 support, powered by [ngx_http_geoip2_module](https://github.com/leev/ngx_http_geoip2_module) 24 | - Headers More support, powered by [ngx_headers_more](https://github.com/openresty/headers-more-nginx-module) 25 | - Remove mountains of useless modules to improve performance 26 | 27 | ## Usage 28 | 29 | Run following commands. 30 | 31 | ```bash 32 | wget https://github.com/ononoki1/nginx-http3/releases/latest/download/nginx.deb 33 | sudo apt install ./nginx.deb 34 | ``` 35 | 36 | ## Removed modules 37 | 38 | - All modules that are not built by default, except `http_ssl_module`, `http_v2_module` and `http_v3_module` 39 | - `http_access_module` 40 | - `http_autoindex_module` 41 | - `http_browser_module` 42 | - `http_charset_module` 43 | - `http_empty_gif_module` 44 | - `http_limit_conn_module` 45 | - `http_memcached_module` 46 | - `http_mirror_module` 47 | - `http_referer_module` 48 | - `http_split_clients_module` 49 | - `http_scgi_module` 50 | - `http_ssi_module` 51 | - `http_upstream_hash_module` 52 | - `http_upstream_ip_hash_module` 53 | - `http_upstream_keepalive_module` 54 | - `http_upstream_least_conn_module` 55 | - `http_upstream_random_module` 56 | - `http_upstream_zone_module` 57 | 58 | ## Add modules back 59 | 60 | Fork this repo, enable GitHub Actions, edit `build.sh` and find the modules you want. Then remove related parameters and wait for GitHub Actions to run. After it finishes, you can download from releases. 61 | 62 | For example, if you want to add `http_scgi_module` back, you need to remove `--http-scgi-temp-path=/var/cache/nginx/scgi_temp` and `--without-http_scgi_module` in `build.sh`. 63 | 64 | ## Use in another distribution 65 | 66 | Fork this repo, enable GitHub Actions, edit `Dockerfile` and `build.sh`, and change `bookworm` to the one you like. Then wait for GitHub Actions to run. After it finishes, you can download from releases. 67 | 68 | For example, if you want to use in Debian bullseye, you need to change `bookworm` to `bullseye`. 69 | 70 | Note: if you are using newer version of Debian (e.g. Debian trixie or unstable), you can still use releases for Debian bookworm as Debian is backward compatible. 71 | 72 | ## Recommended NGINX config 73 | 74 | ```nginx 75 | http { 76 | brotli on; 77 | gzip on; 78 | http2 on; 79 | http3 on; 80 | quic_gso on; 81 | quic_retry on; 82 | ssl_certificate /path/to/cert_plus_intermediate; 83 | ssl_certificate_key /path/to/key; 84 | ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305; # change `ECDSA` to `RSA` if you use RSA certificate 85 | ssl_early_data on; 86 | ssl_protocols TLSv1.2 TLSv1.3; 87 | ssl_session_cache shared:SSL:10m; 88 | ssl_session_timeout 1d; 89 | ssl_stapling on; 90 | ssl_stapling_verify on; 91 | server { 92 | listen 80 reuseport; 93 | listen [::]:80 reuseport; # delete if ipv6 is unavailable 94 | return 444; 95 | } 96 | server { 97 | listen 443 reuseport ssl; 98 | listen [::]:443 reuseport ssl; 99 | listen 443 reuseport quic; 100 | listen [::]:443 reuseport quic; 101 | ssl_reject_handshake on; 102 | } 103 | server { 104 | listen 80; 105 | listen [::]:80; 106 | server_name example.com dynamic.example.com php.example.com www.example.com; 107 | return 308 https://$host$request_uri; 108 | } 109 | server { # example for static site 110 | listen 443; 111 | listen [::]:443; 112 | listen 443 quic; 113 | listen [::]:443 quic; 114 | server_name example.com; 115 | root /path/to/static/site; 116 | add_header Alt-Svc 'h3=":443"; ma=86400'; 117 | } 118 | server { # example for dynamic site 119 | listen 443; 120 | listen [::]:443; 121 | listen 443 quic; 122 | listen [::]:443 quic; 123 | server_name dynamic.example.com; 124 | add_header Alt-Svc 'h3=":443"; ma=86400'; 125 | location / { 126 | proxy_pass http://ip:port; 127 | } 128 | } 129 | server { # example for dynamic site with php 130 | listen 443; 131 | listen [::]:443; 132 | listen 443 quic; 133 | listen [::]:443 quic; 134 | server_name php.example.com; 135 | root /path/to/php/site; 136 | index index.php; 137 | add_header Alt-Svc 'h3=":443"; ma=86400'; 138 | location ~ ^.+\.php$ { 139 | include fastcgi_params; 140 | fastcgi_param HTTP_PROXY ''; 141 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 142 | fastcgi_pass unix:/path/to/php/sock; 143 | } 144 | } 145 | server { 146 | listen 443; 147 | listen [::]:443; 148 | listen 443 quic; 149 | listen [::]:443 quic; 150 | server_name www.example.com; 151 | add_header Alt-Svc 'h3=":443"; ma=86400'; 152 | return 308 https://example.com$request_uri; 153 | } 154 | } 155 | ``` 156 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## NO WARRANTY 4 | 5 | THE SERVICE AND ANY RELATED SERVICES ARE PROVIDED ON AN "AS IS" AND "AS AVAILABLE" BASIS, WITHOUT WARRANTY OF ANY KIND, WHETHER WRITTEN OR ORAL, EXPRESS OR IMPLIED. I DISCLAIM ALL IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO ALL WARRANTIES OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. I DO NOT REPRESENT OR WARRANT THAT THE SERVICE WILL MEET CLIENT'S NEEDS OR REQUIREMENTS, THAT ANY INFORMATION OBTAINED THROUGH USE OF THE SERVICE WILL BE ACCURATE OR RELIABLE, THAT USE OF THE SERVICE WILL BE UNINTERRUPTED, TIMELY, SECURE OR FREE FROM ERROR, OR THAT ALL DEFECTS IN THE SERVICE WILL BE CORRECTED. 6 | -------------------------------------------------------------------------------- /action.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | runs: 3 | using: docker 4 | image: Dockerfile 5 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | cd /github/home 3 | echo Install dependencies. 4 | echo deb http://deb.debian.org/debian bullseye-backports main >> /etc/apt/sources.list 5 | apt-get update > /dev/null 2>&1 6 | apt-get install --allow-change-held-packages --allow-downgrades --allow-remove-essential \ 7 | -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confold -fy \ 8 | cmake git libmaxminddb-dev wget > /dev/null 2>&1 9 | wget -qO /etc/apt/trusted.gpg.d/nginx_signing.asc https://nginx.org/keys/nginx_signing.key 10 | echo deb-src https://nginx.org/packages/mainline/debian bullseye nginx \ 11 | >> /etc/apt/sources.list 12 | echo -e 'Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900' \ 13 | > /etc/apt/preferences.d/99nginx 14 | apt-get update > /dev/null 2>&1 15 | apt-get build-dep --allow-change-held-packages --allow-downgrades --allow-remove-essential \ 16 | -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confold -fy \ 17 | nginx > /dev/null 2>&1 18 | echo Fetch NGINX source code. 19 | apt-get source nginx > /dev/null 2>&1 20 | echo Fetch quictls source code. 21 | cd nginx-* 22 | mkdir debian/modules 23 | cd debian/modules 24 | git clone --depth 1 --recursive https://github.com/quictls/openssl > /dev/null 2>&1 25 | echo Fetch additional dependencies. 26 | git clone --depth 1 --recursive https://github.com/google/ngx_brotli > /dev/null 2>&1 27 | mkdir ngx_brotli/deps/brotli/out 28 | cd ngx_brotli/deps/brotli/out 29 | cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX=installed .. \ 30 | > /dev/null 2>&1 31 | cmake --build . --config Release --target brotlienc > /dev/null 2>&1 32 | cd ../../../.. 33 | git clone --depth 1 --recursive https://github.com/leev/ngx_http_geoip2_module > /dev/null 2>&1 34 | git clone --depth 1 --recursive https://github.com/openresty/headers-more-nginx-module > /dev/null 2>&1 35 | echo Build nginx. 36 | cd .. 37 | sed -i 's|NGINX Packaging |ononoki |g' control 38 | sed -i 's|export DEB_CFLAGS_MAINT_APPEND=.*|export DEB_CFLAGS_MAINT_APPEND=|g' rules 39 | sed -i 's|export DEB_LDFLAGS_MAINT_APPEND=.*|export DEB_LDFLAGS_MAINT_APPEND=|g' rules 40 | sed -i 's|CFLAGS=""|CFLAGS="-Wno-error"|g' rules 41 | sed -i 's|--sbin-path=/usr/sbin/nginx|--sbin-path=/usr/sbin/nginx --add-module=$(CURDIR)/debian/modules/ngx_brotli --add-module=$(CURDIR)/debian/modules/ngx_http_geoip2_module --add-module=$(CURDIR)/debian/modules/headers-more-nginx-module|g' rules 42 | sed -i 's|--http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx|--user=www-data --group=www-data|g' rules 43 | sed -i 's|--with-compat||g' rules 44 | sed -i 's|--with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module|--with-http_ssl_module|g' rules 45 | sed -i 's|--with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module|--with-pcre-jit --without-select_module --without-poll_module --without-http_access_module --without-http_autoindex_module --without-http_browser_module --without-http_charset_module --without-http_empty_gif_module --without-http_limit_conn_module --without-http_memcached_module --without-http_mirror_module --without-http_referer_module --without-http_split_clients_module --without-http_scgi_module --without-http_ssi_module --without-http_upstream_hash_module --without-http_upstream_ip_hash_module --without-http_upstream_keepalive_module --without-http_upstream_least_conn_module --without-http_upstream_random_module --without-http_upstream_zone_module --with-openssl=$(CURDIR)/debian/modules/openssl|g' rules 46 | cd .. 47 | dpkg-buildpackage -b > /dev/null 2>&1 48 | cd .. 49 | cp nginx_*.deb nginx.deb 50 | hash=$(sha256sum nginx.deb | awk '{print $1}') 51 | patch=$(cat /github/workspace/patch) 52 | minor=$(cat /github/workspace/minor) 53 | if [[ $hash != $(cat /github/workspace/hash) ]]; then 54 | echo $hash > /github/workspace/hash 55 | if [[ $GITHUB_EVENT_NAME == push ]]; then 56 | patch=0 57 | minor=$(($(cat /github/workspace/minor)+1)) 58 | echo $minor > /github/workspace/minor 59 | else 60 | patch=$(($(cat /github/workspace/patch)+1)) 61 | fi 62 | echo $patch > /github/workspace/patch 63 | change=1 64 | echo This is a new version. 65 | else 66 | echo This is an old version. 67 | fi 68 | echo -e "hash=$hash\npatch=$patch\nminor=$minor\nchange=$change" >> $GITHUB_ENV 69 | -------------------------------------------------------------------------------- /hash: -------------------------------------------------------------------------------- 1 | a786789e1fb87c8789eac4be064a4356d92e8c1045445e339129f9be26dc05f6 2 | -------------------------------------------------------------------------------- /minor: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /patch: -------------------------------------------------------------------------------- 1 | 9 2 | --------------------------------------------------------------------------------