Implementasi HTTP3 QUIC pada Nginx (build from source)
H3 atau HTTP3 merupakan protokol HTTP versi 3 yang dikabarkan memiliki peningkatan pada keandalan dan performa pertukaran data. Protokol ini menggunakan UDP sehingga proses pertukaran data lebih cepat dan efisien. Di sini saya akan memberikan tutorial implementasi protokol HTTP3 pada webserver Nginx menggunakan Debian.
Di sini saya menggunakan docker.
service docker start
docker pull debian
docker run -it debian bash
Jika kalian tidak menggunakan docker, kalian bisa menjalankan command command selanjutnya secara langsung (tanpa melalui docker container).
apt-get update && apt-get upgrade -y && apt-get dist-upgrade -y
apt-get install dialog mercurial gcc-multilib git cmake g++
apt-get install curl
apt-get install libunwind-dev
apt-get install nano
apt-get install nginx-common
rm /usr/share/nginx/modules
install rustup (https://rustup.rs)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source $HOME/.cargo/env
Saya akan melakukan clone package yang dibutuhkan dan menaruhnya pada satu folder. Saya menggunakan direktori home. Masuk ke direktori home.
cd /home
Selanjutnya clone Quiche dari Cloudflare dan install Cargo
git clone --recursive https://github.com/cloudflare/quiche
cd /home/quiche
cargo build --examples
cargo test
Kembali ke direktori home
cd /home
Download nginx.
Versi terbaru saat ini yaitu 1.19.3
curl -O https://nginx.org/download/nginx-1.19.3.tar.gz
tar xzvf nginx-1.19.3.tar.gz
Patch nginx agar mendukung modul HTTP versi 3
cd nginx-1.19.3
patch -p01 < ../quiche/extras/nginx/nginx-1.16.patch
Kembali lagi ke direktori home
cd /home
Clone modul header nginx
git clone https://github.com/openresty/headers-more-nginx-module.git
Clone BoringSSL
apt-get install -y build-essential cmake git gnupg golang libpcre3-dev curl zlib1g-dev libcurl4-openssl-dev libssl-dev
git clone https://boringssl.googlesource.com/boringssl
Build BoringSSL from source
cd boringssl
mkdir build
cd build
cmake ..
make
Masuk direktori nginx
cd /home/nginx-1.19.3
Compile nginx dengan modul HTTP3 dan BoringSSL
./configure --with-debug \
--prefix=/usr/share/nginx \
--sbin-path=/usr/sbin/nginx \
--modules-path=/usr/share/nginx/modules \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--pid-path=/run/nginx.pid \
--lock-path=/var/lock/nginx.lock \
--user=www-data \
--group=www-data \
--with-threads \
--with-file-aio \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_slice_module \
--with-http_stub_status_module \
--http-fastcgi-temp-path=/var/lib/nginx/fastcgi \
--without-select_module \
--without-poll_module \
--without-mail_pop3_module \
--without-mail_imap_module \
--without-mail_smtp_module \
--add-dynamic-module=../headers-more-nginx-module \
--build="quiche-$(git --git-dir=../quiche/.git rev-parse --short HEAD)" \
--with-http_v3_module \
--with-openssl=../quiche/deps/boringssl \
--with-quiche=../quiche \
--with-cc-opt="-I../boringssl/include" \
--with-ld-opt="-L../boringssl/build/ssl \
-L../boringssl/build/crypto"
make
make install
Buat folder untuk menampung file SSL
mkdir /etc/ssl/mywebsite/
Exit dari docker container
exit
Commit container dan buat docker image baru dengan nama "mywebsite"
docker ps -a
docker commit CONTAINER_ID mywebsite
Hapus docker container
docker rm CONTAINER_ID
Jalankan docker image yang baru dan forward port yang dibutuhkan untuk website
docker run -it -p 80:80 -p 443:443/tcp -p 443:443/udp mywebsite
Keluar dari docker container yang baru tetapi tetap biarkan status container UP atau berjalan
tekan CTRL+P
setelah itu tekan CTRL+Q
Siapkan sertifikat SSL di server kamu. Kamu tidak bisa menggunakan sertifikat dari cloudflare. Jadi kamu harus generate sertifikat ssl sendiri di server kamu. Di sini saya menggunakan sertifikat gratis dari Let's Encrypt. Sebelumnya, pastikan A record domain sudah mengarah ke IP server kita. Pastikan juga port 80 dalam keadaan free (tidak sedang digunakan)
certbot certonly --standalone --non-interactive --agree-tos -d yourdomain.com -m youremail@gmail.com
Copy file SSL ke docker container yang berjalan
docker exec -i CONTAINER_ID sh -c 'cat > /etc/ssl/mywebsite/fullchain.pem' < /home/fullchain.pem
docker exec -i CONTAINER_ID sh -c 'cat > /etc/ssl/mywebsite/privkey.pem' < /home/privkey.pem
Masuk kembali ke terminal docker container
docker exec -it CONTAINER_ID bash
Ubah permission file SSL
chmod -R 777 /etc/ssl/mywebsite/
Konfigurasi nginx HTTP3
nano /etc/nginx/nginx.conf
Tambahkan kode berikut ke dalam bagian "http" :
http {
server {
listen 443 quic reuseport;
listen 443 ssl http2;
proxy_request_buffering off;
ssl_early_data on;
ssl_certificate /etc/ssl/mywebsite/fullchain.pem;
ssl_certificate_key /etc/ssl/mywebsite/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
add_header Alt-Svc 'h3-29=":443"; ma=2592000, h3-28=":443"; ma=2592000, H3-27=":443"; ma=2592000, h3-Q050=":443"; ma=2592000, h3-Q046=":443"; ma=2592000, h3-Q043=":443"; ma=2592000, quic=":443"; ma=2592000; v="46,43"';
}
}
Contoh hasil jadi konfigurasi nginx:
user www-data;
load_module modules/ngx_http_headers_more_filter_module.so;
worker_processes auto;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
gzip on;
server {
listen 80;
listen [::]:80;
server_name _;
access_log off;
error_log off;
return 301 https://yourdomain.com$request_uri;
}
server {
listen 443 quic reuseport default_server;
listen 443 ssl http2;
proxy_request_buffering off;
client_max_body_size 100M;
server_name yourdomain.com;
ssl_early_data on;
ssl_certificate /etc/letsencrypt/mywebsite/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/mywebsite/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
add_header Alt-Svc 'h3-29=":443"; ma=2592000, h3-28=":443"; ma=2592000, H3-27=":443"; ma=2592000, h3-Q050=":443"; ma=2592000, h3-Q046=":443"; ma=2592000, h3-Q043=":443"; ma=2592000, quic=":443"; ma=2592000; v="46,43"';
root /var/www/html/projek;
location '/.well-known/acme-challenge' {
default_type "text/plain";
root /var/www/html/projek;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
fastcgi_read_timeout 120;
fastcgi_param HTTP_IF_NONE_MATCH $http_if_none_match;
fastcgi_param HTTP_IF_MODIFIED_SINCE $http_if_modified_since;
}
}
}
Test konfigurasi nginx:
nginx -t
Jika tidak ada error pada konfigurasi nginx, jalankan web server nginx
service nginx start
Terakhir, cek domain website kamu di http3check.net/
Jika berhasil hasilnya seperti gambar di bawah ini:
Jika ada kesulitan, bisa melihat video implementasi langsung melalui terminal linux di youtube
Selamat mencoba 😇