HTTP/2 หรือ (เดิมเรียกว่า HTTP/2.0) เป็นมาตรฐานใหม่ของ web protocol ซึ่งจะมาแทนที่ HTTP/1.1 ซึ่งออกมาตั้งแต่ 1997 (RFC 2068) และใช้อยู่จนถึงปัจจุบัน ความจริงแล้วเจ้า HTTP/2 นั้น มันได้ต่อยอดการพัฒนามาจาก Project SPDY ของ Google จะเห็นว่าเว็บใหญ่ๆหลายๆ เว็บอย่างเช่น Google, Twitter ก็หันมาใช้ HTTP/2 กันแล้ว ในขณะเดียวกัน ตอนนี้ ทาง Facebook มีการพัฒนาต่อยอดเป็น SPDY 3.1 ไปเรียบร้อยแล้ว ^ ^”
ในตอนนี้ทาง IESG ได้ออกมาประกาศให้ HTTP/2 เป็นมาตรฐานเรียบร้อยแล้ว โดยข้อตกลงนี้ถูกร่างเอาไว้ใน RFC 7540 ตั้งแต่ May 2015
จากที่ผมได้หาข้อมูลมาจากหลายๆเว็บ และดูจากผลการทดสอบ จะเห็นว่า HTTP/2 จะมีข้อดีกว่า และเร็วกว่า HTTP/1.1 อยู่หลาายๆ ข้อ เหมือนกัน อย่างเช่น จะเห็นว่า Header ของ HTTP/2 จะมีการ Compression ชึ่งใช้เทคนิคที่เรียกว่า HPACK (Header Compression for HTTP/2) ทำให้ลดการซ้ำซ้อนของ Header ใน request ทำให้ส่งข้อมูลได้เร็วขึ้น และลดจำนวน request ลง โดยจากต่างจาก HTTP/1.1 ซึ่งเป็นแบบ stateless คือ request อะไรไป จะรอจนกว่าจะได้ response อีกอย่างและข้อมูลที่ผ่าน HTTP/2 นั้นจะมีการ Encrypt เสมอ จะเห็นว่าเมือเราทำการเปิดใช้งาน http2 ใน web server นั้น มันจะบังคับให้เปิดใช้งาน SSL/TLS ด้วย ดังนั้นเราต้องจำเป็นต้องมี SSL Certificate นั่นเอง
บทความนี้ เป็นบทความที่ต่อจากคราวที่แล้ว ที่ผมได้พูดถึงขึ้นตอนการ Upgraded PHP 7 บน Vesta CP ไปแล้ว สำหรับใครสนใจก็กด link เข้าไปอ่านได้เลยครับ
“วิธีเปิดใช้งาน PHP 7 บน Vesta CP เพื่อใช้งานร่วมกับ Nginx + PHP-FPM” ในวันนี้ผมเลยอยากจะลอง upgrade server ของผมให้รองรับ HTTP/2 กับเค้าสะหน่อยจะได้ไม่ตกเทรนด์ ^ ^ ในการทดสอบครั้งนี้ผมใช้ VPS Linux Server (Digital Ocean) ของผมเอง โดย OS ณ. ตอนนี้ เป็น CentOS 7 x64 และรวมไปถึงการ upgrade Nginx version เก่า ให้เป็น Version ใหม่ เพื่อให้รองรับ HTTP/2 ไปด้วย ว่าแล้วมาเริ่มกันนเลยครับ
1 2 3 4 5 |
# nginx -V nginx version: nginx/1.8.0 built by gcc 4.8.2 20140120 (Red Hat 4.8.2-16) (GCC) built with OpenSSL 1.0.1e-fips 11 Feb 2013 TLS SNI support enabled |
หลังจากตรวจสอบ Version ของ Nginx ที่ติดมากับ Vesta CP นั้นจะเห็นว่ามันยังคงเป็น version 1.8.X อยู่เลย ซึ่งมันยังไม่ support HTTP/2.0 ที่นี้่เราจะต้องทำการ Upgrade มันเพื่อให้เป็น Version 1.9.5 ขึ้นไป ถึงจะรองรับ HTTP/2.0
ก่อนอื่นเลยให้ทำการแก้ไข respo ของ nginx ให้ชี้ไปที่ http://nginx.org/packages/mainline/centos/$releasever/$basearch/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
sudo vi /etc/yum.repos.d/nginx.repo Config เดิม [nginx] name=nginx repo baseurl=http://nginx.org/packages/centos/7/$basearch/ gpgcheck=0 enabled=1 หลังจาก แก้ไข [nginx] name=nginx repo baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/ gpgcheck=0 enabled=1 |
จากนั้นทำการ Install ทับเข้าไปแทนตัวเก่าได้เลย โดยใช้คำสั่งด้านล่าง
1 |
sudo yum update && sudo yum install nginx |
ทำการตรวจสอบอีกที จะก็ได้ Nginx version ใหม่ล่าสุดล่ะ (จะเห็๋นว่ามี package “–with-http_v2_module” เพิ่มเข้ามาด้วย)
1 2 3 4 5 6 |
# nginx -V nginx version: nginx/1.9.9 built by gcc 4.8.3 20140911 (Red Hat 4.8.3-9) (GCC) built with OpenSSL 1.0.1e-fips 11 Feb 2013 TLS SNI support enabled configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-threads --with-stream --with-stream_ssl_module --with-http_slice_module --with-mail --with-mail_ssl_module --with-file-aio --with-ipv6 --with-http_v2_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic' |
การที่เราจะเปิดใช้งาน HTTP/2.0 นั้น มันจะบังคับให้เราจะต้องเปิดใช้งาน SSL ด้วย ดังนั้นเราจำเป็นจะต้องสร้าง cert ขึ้นมา
หรือถ้าใครไม่มี cert ก็สามารถสร้างขึ้นมาเองก็ได้
กรณีสร้าง Cert ขึ้นมาใช้เองแบบ Self-Signed SSL Certificate
ยกตัวอย่างวิธีสร้าง cert ขึ้นมาใช้เอง (แบบ Self-Signed SSL)
vi /etc/nginx/conf.d/default.conf
1 2 3 4 5 6 7 8 |
cd /etc/nginx/ openssl genrsa -des3 -out server.key 2048 openssl req -new -key server.key -out server.csr cp server.key server.key.org openssl rsa -in server.key.org -out server.key openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt mkdir ssl sudo cp -ip server.crt server.key /etc/nginx/ssl |
vi /home/admin/conf/web/nginx.conf (กรณีถ้าใช้ Vesta CP จะต้อง config ที่ ไฟล์นี้)
จุดที่ต้องการแก้ไขจะมีแค่ 4 บรรทัด
1 2 3 4 |
listen 443 ssl http2; ssl on; ssl_certificate /etc/nginx/ssl/server.crt; ssl_certificate_key /etc/nginx/ssl/server.key; |
ตัวอย่าง ngix.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
server { listen XX.XXX.XXX.XXX:443 ssl http2; <--- ในที่นี้เครื้องผมมี Vesta CP ติดตั้งไว้อยู่ เลยจำเป็นต้องใส่ IP ข้างหน้าด้วย server_name mydomain.com www.mydomain.com; ssl on; ssl_certificate /etc/nginx/ssl/server.crt; ssl_certificate_key /etc/nginx/ssl/server.key; root /home/admin/web/mydomain.com/public_html; index index.php index.html index.htm; access_log /var/log/nginx/domains/mydomain.com.log combined; access_log /var/log/nginx/domains/mydomain.com.bytes bytes; error_log /var/log/nginx/domains/mydomain.com.error.log error; location / { location ~* ^.+\.(jpeg|jpg|png|gif|bmp|ico|svg|css|js)$ { expires max; } location ~ [^/]\.php(/|$) { fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; if (!-f $document_root$fastcgi_script_name) { return 404; } fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; include /etc/nginx/fastcgi_params; } } error_page 403 /error/404.html; ... |
หลังจากแก้ไข config เสร็จ แล้วลองเข้าเว็บอีก โดยเปลียนจาก http เป็น https แล้วลองสังเกต Header Response ดูอีกที ก็จะเห็นว่า nginx ของเราสามารถลองรับ HTTP/2.0 ละ
กรณีใช้งานรวมกับ Opensource SSL (Let’s Encrypt)
สำหรับท่านที่ต้องการใช้ Let’s Encrypt ซึ่งเป็น Open source SSL ก็สามารถนำมาใช้งานกับ Nginx ได้เช่นเดียวกันครับ
1 2 3 |
yum install git yum install epel-release yum install gcc libffi-devel python-devel openssl-devel mod_ssl |
ทำการ download source code ลงมาไว้ที่เครือง และก็ตามด้วยคำสั่งในการสร้าง certificate
1 2 3 4 5 6 |
cd /root git clone https://github.com/letsencrypt/letsencrypt cd letsencrypt service nginx stop (ปิด service nginx ไว้ก่อน ถ้าเปิดไว้มันจะสร้าง cert ไม่สำเร็จ) ./letsencrypt-auto auth -d mydomain.com -d www.mydomain.com --email my-email@gmail.com --text |
หลังจากที่สร้าง certificate let’s encrypt เสร็จ เราจะได้ไฟล์ cert อยู่ 4 ไฟล์ ซึ่งเก็บอยู่ใน
/etc/letsencrypt/live/mydomain.com/
เราจะต้องนำไฟล์เหล่านี้ไป config ไว้ใน config ของ Nginx
vi /home/admin/conf/web/nginx.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
server { listen XX.XX.XX.XX:443 ssl http2; listen XX.XX.XX.XX:80; .... ssl_certificate /etc/letsencrypt/live/mydomain.com/cert.pem; ssl_certificate_key /etc/letsencrypt/live/mydomain.com/privkey.pem; ssl_trusted_certificate /etc/letsencrypt/live/mydomain.com/chain.pem; ssl_stapling on; ssl_stapling_verify on; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; add_header Content-Security-Policy "default-src https: data: 'unsafe-inline' 'unsafe-eval'" always; add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header X-Xss-Protection "1; mode=block" always; ..... |
สำหรับตอนนี้ DH parameters สามารถสร้างได้ตั้งแต่ 2048 bit ขึ้นไปจะดีมาก
ถ้าให้ดีจัดไปสัก 4096 จะแจ่มมากเลย
1 2 3 4 5 |
cd /etc/ssl/certs openssl dhparam -out dhparam.pem 4096 จากนั้นเพิ่มบรรทัดนี้เข้าไปใน config ด้วย ssl_dhparam /etc/ssl/certs/dhparam.pem; |
จากนั้นทำการ restart service อีกที
1 |
nginx -s reload |
หรือจะลองทดสอบผ่าน web ข้างล่างก็ได้เช่นกัน
https://tools.keycdn.com/http2-test
สำหรับบน Browser มันก็จะมี Plug-in ในการ detected HTTP/2.0 & SPDY อยู่นะครับ
อย่างตอนนี้ผมใช้ตัว HTTP/2 and SPDY อยู่ ถ้าใครสงใจก็ลองไปติดตั้งใช้งานดูนะครับ
หวังว่าบทความนี้น่าจะเป็นประโยชน์กับท่านผู้อ่านไม่มากก็น้อย สำหรับท่านที่อยากจะลอง upgrade web server ให้รองรับ HTTP/2.0 และถ้าหากมีข้อผิดพลาดประการใด จึงขออภัยมา ณ ที่นี้ด้วยนะครับ
หรือถ้าหากมีสงสัยตรงไหน ก็สามารถ comment ถามมาได้เลยครับ
ขอบคุณครับ
Admin@Rockdevper
REF
http://www.liberiangeek.net/2015/05/nginx-1-9-1-released-heres-how-to-installupgrade-in-centos-7-and-ubuntu/
http://wata.hateblo.jp/entry/nginx_1_9_5_http2
http://www.frozenshell.com/configure-vestacp-to-use-letsencrypt-certificates/
https://en.wikipedia.org/wiki/HTTP/2
Comments are closed