Jika Anda seorang admin server, Anda mungkin memiliki server web pilihan Anda seperti Apache, atau Nginx. Apache adalah server web yang terkenal sejak tahun 1990-an. Nginx pertama kali dikembangkan pada tahun 2004 dan dengan cepat mendapatkan daya tarik karena jejak memorinya yang ringan dan kecepatan pemrosesan yang cepat untuk file HTML statis.
Baik Apache dan Nginx mendukung hosting virtual, yang berarti Anda dapat meng-host beberapa situs web atau aplikasi web di server yang sama. Namun, Anda akan menghadapi situasi di mana Anda memiliki server web yang sudah berjalan, tetapi aplikasi web tertentu memerlukan penggunaan server web yang berbeda. Port 80 atau 443 pada alamat IP publik hanya dapat digunakan oleh satu proses. Jika Apache menggunakan port tersebut, maka Nginx tidak dapat menggunakan (atau mengikatnya). Jadi apa yang bisa kamu lakukan?
Anda dapat mengonfigurasi Nginx sebagai proxy terbalik ke Apache, sehingga Nginx dapat mengarahkan permintaan HTTP ke Apache. Dalam pengalaman saya, saya menemukan bahwa ini tidak selalu merupakan cara terbaik karena pernah menyebabkan masalah aneh yang tidak dapat saya atasi. Sebaliknya, saya lebih suka menggunakan HAProxy sebagai proxy terbalik untuk Nginx dan Apache . HAProxy adalah server proxy dan penyeimbang beban dengan ketersediaan tinggi sumber terbuka dan gratis untuk aplikasi berbasis TCP dan HTTP.
Jalankan Apache, Nginx dan HAProxy di Server yang Sama
Begini cara kerjanya.
- Nginx mendengarkan pada 127.0.0.1:80 dan 127.0.0.1:443
- Apache mendengarkan pada 127.0.0.2:80 dan 127.0.0.0.2:443
- HAProxy mendengarkan pada port 80 dan 443 alamat IP publik. Ini mengarahkan permintaan HTTP pada port 80 ke port 443. Ketika permintaan tiba di port 443, itu akan memilih antara Nginx dan Apache back end dengan menganalisis header SNI (indikasi nama server) dalam permintaan HTTPS.
Sebenarnya, Cloudflare (penyedia CDN) juga menggunakan header SNI untuk menentukan cara merutekan permintaan HTTPS ke server asal.
Langkah 1:Hentikan Nginx dan Apache
Untuk menghentikan Nginx di Debian, Ubuntu dan CentOS, jalankan
sudo systemctl stop nginx
Untuk menghentikan Apache di Debian/Ubuntu, jalankan
sudo systemctl stop apache2
Untuk menghentikan Apache di CentOS, jalankan
sudo systemctl stop httpd
Langkah 2:Ubah Port Dengarkan di Nginx
Kita perlu membuat Nginx mendengarkan 127.0.0.1:80. Buka file konfigurasi Nginx Anda di /etc/nginx/conf.d/
atau /etc/nginx/sites-enabled/
dan temukan baris berikut.
listen 80;
Ubah ke
listen 127.0.0.1:80;
Jika https diaktifkan di blok server Nginx, temukan juga
listen 443 ssl;
Dan ubah menjadi
listen 127.0.0.1:443 ssl;
File konfigurasi utama Nginx /etc/nginx/nginx.conf
mungkin menyertakan host virtual default yang mendengarkan pada port 80 atau 443, jadi Anda mungkin perlu mengedit file ini juga.
Mulai ulang Nginx agar perubahan diterapkan.
sudo systemctl restart nginx
Langkah 3:Ubah Listen Port di Apache
Kita perlu membuat Apache mendengarkan pada 127.0.0.2:80.
Debian/Ubuntu
Di Debian dan Ubuntu, edit /etc/apache2/ports.conf
berkas.
sudo nano /etc/apache2/ports.conf
Ubah
Listen 80 Listen 443
Untuk
Listen 127.0.0.2:80 Listen 127.0.0.2:443
Simpan dan tutup file. Buka juga /etc/apache2/sites-enabled/
direktori, edit file host virtual. Ubah
<VirtualHost *:80>
Untuk
<VirtualHost 127.0.0.2:80>
Jika ada host virtual SSL, maka ubah juga
<VirtualHost *:443>
Untuk
<VirtualHost 127.0.0.2:443>
Mulai ulang Apache.
sudo systemctl restart apache2
CentOS
Pada CentOS, edit /etc/httpd/conf/httpd.conf
berkas.
sudo nano /etc/httpd/conf/httpd.conf
Temukan
Listen 80
Ubah ke
Listen 127.0.0.2:80
Simpan dan tutup file. Lalu pergi ke /etc/httpd/conf.d/
direktori, edit file host virtual. Ubah
<VirtualHost *:80>
Untuk
<VirtualHost 127.0.0.2:80>
Jika ada host virtual SSL, maka ubah juga
<VirtualHost *:443>
Untuk
<VirtualHost 127.0.0.2:443>
Dalam /etc/httpd/conf.d/ssl.conf
file, ada
Listen 443 https
Ubah ke:
Listen 127.0.0.2:443 https
Simpan dan tutup file. Mulai ulang Apache agar perubahan diterapkan.
sudo systemctl restart httpd
Langkah 4:Konfigurasi HAProxy
Instal HAProxy di distro Anda.
Debian/Ubuntu
sudo apt install haproxy
CentOS
sudo dnf install haproxy
Edit file konfigurasi HAProxy.
sudo nano /etc/haproxy/haproxy.cfg
Tambahkan cuplikan kode berikut di akhir file, yang akan membuat HAPorxy mendengarkan alamat IP publik port 80 dan mengalihkan permintaan HTTP pada port 80 ke port 443. Ganti 12.34.56.78 dengan alamat IP publik server Anda.
frontend http bind 12.34.56.78:80 mode http redirect scheme https code 301
Sekarang kita juga perlu menambahkan front end HTTPS.
frontend https bind 12.34.56.78:443 mode tcp tcp-request inspect-delay 5s tcp-request content accept if { req_ssl_hello_type 1 }
Kemudian tentukan ujung belakang Nginx dan Apache. check
parameter memberitahu HAProxy untuk melakukan pemeriksaan kesehatan di back-end dengan mengirimkan paket TCP.
backend nginx mode tcp option ssl-hello-chk server nginx 127.0.0.1:443 check backend apache mode tcp option ssl-hello-chk server apache 127.0.0.2:443 check
Anda dapat menentukan back end default dengan:
default_backend nginx
Kami akan menggunakan header SNI dalam permintaan HTTPS untuk mengarahkan ulang ke back end yang benar. Misalnya, jika Nginx melayani domain1.com
dan Apache melayani domain2.com
, lalu tambahkan dua baris berikut. Anda juga dapat menggunakan subdomain, asalkan berbeda.
use_backend nginx if { req_ssl_sni -i domain1.com } use_backend apache if { req_ssl_sni -i domain2.com }
Perhatikan bahwa default_backend
dan use_backend
arahan harus ditempatkan di atas definisi backend.
frontend http bind 12.34.56.78:80 mode http redirect scheme https code 301 frontend https bind 12.34.56.78:443 mode tcp tcp-request inspect-delay 5s tcp-request content accept if { req_ssl_hello_type 1 } default_backend nginx use_backend nginx if { req_ssl_sni -i domain1.com } use_backend apache if { req_ssl_sni -i domain2.com } backend nginx mode tcp option ssl-hello-chk server nginx 127.0.0.1:443 check backend apache mode tcp option ssl-hello-chk server apache 127.0.0.2:443 check
Pada konfigurasi di atas, kami menggunakan fitur SNI (Server Name Indication) di TLS untuk membedakan traffic HTTPS.
- Saat domain1.com ada di TLS Client Halo, HAProxy mengalihkan lalu lintas ke
nginx
bagian belakang. - Saat domain2.com ada di TLS Client Halo, HAProxy mengalihkan lalu lintas ke
apache
bagian belakang.
Jika klien tidak menentukan nama server di TLS Client Hello, maka HAproxy akan menggunakan backend default (nginx).
Simpan dan tutup file. Kemudian restart HAproxy.
sudo systemctl restart haproxy
Sekarang Apache, Nginx, dan HAProxy dapat berjalan di server yang sama.
Cara Meneruskan alamat IP Klien ke Backend
Secara default, Apache dan Nginx hanya dapat melihat alamat IP HAProxy. Untuk mendapatkan alamat IP asli klien, pastikan Anda menambahkan send-proxy-v2
opsi dalam definisi ujung belakang HAProxy seperti di bawah ini.
backend nginx mode tcp option ssl-hello-chk server nginx 127.0.0.1:443 send-proxy-v2 check backend apache mode tcp option ssl-hello-chk server apache 127.0.0.2:443 send-proxy-v2 check
Kami juga perlu menambahkan beberapa konfigurasi di Nginx dan Apache untuk membuatnya berfungsi, jika tidak, situs web Anda tidak akan dapat diakses.
Nginx
Tambahkan proxy_protocol
di Nginx listen
arahan seperti di bawah ini.
listen 127.0.0.2:443 ssl http2 proxy_protocol;
Kemudian tambahkan dua arahan berikut di Nginx http { }
blokir di /etc/nginx/nginx.conf
berkas.
set_real_ip_from 127.0.0.1; real_ip_header proxy_protocol;
Simpan dan tutup file. Kemudian muat ulang Nginx.
sudo systemctl reload nginx
Catatan :Jika situs web Anda berjalan di belakang Cloudflare CDN, maka Anda harus mengubah real_ip_header proxy_protocol;
ke real_ip_header CF-Connecting-IP;
untuk menunjukkan alamat IP asli klien. Anda juga dapat menambahkan real_ip_header
ini direktif ke file blok server individu untuk menimpa konfigurasi global di /etc/nginx/nginx.conf
berkas.
Terakhir, mulai ulang HAProxy.
sudo systemctl restart haproxy
Apache
Jika Anda menggunakan Apache di Debian/Ubuntu, Anda harus mengaktifkan remoteip modul. (Modul ini diaktifkan pada CentOS secara default.)
sudo a2enmod remoteip
Kemudian tambahkan 3 baris berikut di file konfigurasi virtual host Apache Anda.
RemoteIPProxyProtocol On RemoteIPHeader X-Forwarded-For RemoteIPTrustedProxy 127.0.0.1
Seperti ini.
<VirtualHost 127.0.0.2:443> ServerName www.example.com RemoteIPProxyProtocol On RemoteIPHeader X-Forwarded-For RemoteIPTrustedProxy 127.0.0.1
Simpan dan tutup file. Kemudian kita juga perlu mengubah combined
format log. Edit file konfigurasi utama Apache.
sudo nano /etc/apache2/apache2.conf
atau
sudo nano /etc/httpd/conf/httpd.conf
Temukan baris berikut.
LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
Ganti dengan:
LogFormat "%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
Simpan dan tutup file. Kemudian restart Apache agar perubahan diterapkan.
sudo systemctl restart apache2
atau
sudo systemctl restart httpd
Catatan bahwa RemoteIPProxyProtocol On
direktif hanya tersedia di Apache 2.4.31 dan yang lebih baru. Untuk memeriksa versi Apache Anda, jalankan
sudo apache2 -v
atau
sudo httpd -v
Ubuntu 18.04 dikirimkan dengan Apache 2.4.29. Jika versi Apache Anda tidak memenuhi persyaratan ini, maka Anda harus menghapus send-proxy-v2
dalam definisi ujung belakang HAProxy. CentOS 8 dikirimkan dengan Apache 2.4.37.
Terakhir, mulai ulang HAProxy.
sudo systemctl restart haproxy
Cara Menambahkan Host Virtual Baru
Jika Anda memiliki server web Apache dan Nginx, maka Anda hanya memerlukan dua backend:satu untuk Apache dan satu untuk Nginx.
Saat Anda perlu menambahkan domain (atau subdomain) lain, Anda tidak perlu menambahkan backend baru di HAProxy. Sebagai gantinya, Anda harus membuat host virtual baru untuk domain (atau sub-domain) baru di Apache atau Nginx, lalu gunakan use_backend
direktif di HAProxy untuk mengarahkan lalu lintas ke backend yang benar.
frontend http bind 12.34.56.78:80 mode http redirect scheme https code 301 frontend https bind 12.34.56.78:443 mode tcp tcp-request inspect-delay 5s tcp-request content accept if { req_ssl_hello_type 1 } default_backend nginx use_backend nginx if { req_ssl_sni -i domain1.com } use_backend nginx if { req_ssl_sni -i sub.domain1.com } use_backend apache if { req_ssl_sni -i domain2.com } use_backend apache if { req_ssl_sni -i sub.domain2.com } backend nginx mode tcp option ssl-hello-chk server nginx 127.0.0.1:443 check backend apache mode tcp option ssl-hello-chk server apache 127.0.0.2:443 check
Saya sarankan menggunakan apache
dan nginx
seperti nama backend seperti pada kode di atas, jadi Anda tahu server web mana yang menghosting aplikasi mana.
Mendapatkan Sertifikat SSL Let's Encrypt Baru
tantangan http-01
Pertama, Anda perlu memahami cara menggunakan Certbot apache dan nginx authenticator untuk mendapatkan sertifikat TLS.
- Aktifkan HTTPS di Apache dengan Benar dengan Let's Encrypt di Ubuntu
- Aktifkan HTTPS di Nginx dengan Benar dengan Let's Encrypt di Ubuntu
Apache Certbot dan autentikator nginx menggunakan http-01
challenge, yang bekerja pada port TCP 80. Karena HAProxy menggunakan port TCP 80, maka http-01
Certbot tantangan cenderung gagal. Namun, Anda dapat membuatnya bekerja dengan metode berikut.
- Aktifkan host SSL di Apache atau Nginx dengan sertifikat yang ditandatangani sendiri atau sertifikat untuk domain lain.
- Kemudian gunakan Certbot apache dan nginx authenticator seperti biasa.
Cara ini berhasil karena Certbot http-01
tantangan dapat dialihkan dari port TCP 80 ke port TCP 443, dan Certbot menerima sertifikat yang tidak valid pada port 443.
tantangan dns-01
Anda juga dapat menggunakan certbot dns-01
challenge, yang bekerja dengan membuat data TXT sementara untuk domain Anda untuk menyatakan bahwa Anda benar-benar memiliki domain ini, sehingga domain ini dapat melewati port TCP 80 dan port TCP 443. Kerugian dari metode ini adalah tidak semua pendaftar domain didukung.
Pertama, Anda perlu menginstal plugin DNS Certbot. Ini adalah beberapa plugin DNS yang tersedia di repositori perangkat lunak Debian dan Ubuntu, yang dapat Anda temukan dengan
apt search python3-certbot-dns
Keluaran:
python3-certbot-dns-cloudflare/bionic,bionic 0.23.0-1 all Cloudflare DNS plugin for Certbot python3-certbot-dns-digitalocean/bionic,bionic 0.23.0-1 all DigitalOcean DNS plugin for Certbot python3-certbot-dns-dnsimple/bionic,bionic 0.23.0-1 all DNSimple DNS plugin for Certbot python3-certbot-dns-google/bionic,bionic 0.23.0-1 all Google DNS plugin for Certbot python3-certbot-dns-rfc2136/bionic,bionic 0.23.0-1 all RFC 2136 DNS plugin for Certbot python3-certbot-dns-route53/bionic,bionic 0.23.0-1 all Route53 DNS plugin for Certbot
Di CentOS 8, Anda dapat menemukan plugin DNS Certbot dari repositori EPEL. Perhatikan bahwa Anda perlu menginstal Certbot dari repositori CentOS default.
sudo dnf install certbot
Temukan plugin DNS dari repositori EPEL.
sudo dnf install epel-release dnf search certbot-dns
Keluaran:
python3-certbot-dns-ovh.noarch : OVH DNS Authenticator plugin for Certbot python3-certbot-dns-nsone.noarch : NS1 DNS Authenticator plugin for Certbot python3-certbot-dns-gehirn.noarch : Gehirn Infrastructure Service DNS Authenticator plugin for Certbot python3-certbot-dns-google.noarch : Google Cloud DNS Authenticator plugin for Certbot python3-certbot-dns-linode.noarch : Linode DNS Authenticator plugin for Certbot python3-certbot-dns-luadns.noarch : LuaDNS Authenticator plugin for Certbot python3-certbot-dns-rfc2136.noarch : RFC 2136 DNS Authenticator plugin for Certbot python3-certbot-dns-route53.noarch : Route53 DNS Authenticator plugin for Certbot python3-certbot-dns-cloudxns.noarch : CloudXNS DNS Authenticator plugin for Certbot python3-certbot-dns-dnsimple.noarch : DNSimple DNS Authenticator plugin for Certbot python3-certbot-dns-cloudflare.noarch : Cloudflare DNS Authenticator plugin for Certbot python3-certbot-dns-cloudflare.noarch : Cloudflare DNS Authenticator plugin for Certbot python3-certbot-dns-dnsmadeeasy.noarch : DNS Made Easy DNS Authenticator plugin for Certbot python3-certbot-dns-sakuracloud.noarch : Sakura Cloud DNS Authenticator plugin for Certbot
Instal salah satu plugin ini sesuai dengan layanan hosting DNS yang Anda gunakan. Saya menggunakan Cloudflare, jadi saya akan menggunakan Cloudflare sebagai contoh. Jalankan perintah berikut untuk menginstal python3-certbot-dns-cloudflare
paket di Debian/Ubuntu.
sudo apt install python3-certbot-dns-cloudflare
Kemudian buat file konfigurasi untuk Cloudflare.
sudo nano /etc/letsencrypt/cloudflare.ini
Kami perlu menambahkan alamat email akun Cloudflare dan kunci API kami di file ini.
# Cloudflare API credentials used by Certbot dns_cloudflare_email = [email protected] dns_cloudflare_api_key = 0123456789abcdef0123456789abcdef01234567
Anda dapat menemukan kunci API Cloudflare Anda di https://dash.cloudflare.com/profile
. Perhatikan bahwa plugin Certbot Cloudflare saat ini tidak mendukung "Token API" Cloudflare, jadi pastikan Anda menggunakan "Kunci API Global" untuk otentikasi.
Simpan dan tutup file. Kunci API melewati autentikasi dua faktor Cloudflare, jadi Anda hanya boleh mengizinkan pengguna root untuk membaca file ini.
sudo chmod 600 /etc/letsencrypt/cloudflare.ini
Sekarang jalankan certbot.
sudo certbot --agree-tos -a dns-cloudflare -i nginx --redirect --hsts --staple-ocsp --email [email protected] -d www.your-domain.com,your-domain.com
Pada perintah di atas, kami menentukan bahwa kami akan menggunakan dns-cloudflare
sebagai autentikator untuk mendapatkan sertifikat TLS baru dan menggunakan nginx
plugin untuk membuat blok server HTTPS. Jika Anda menggunakan Apache, maka ganti nginx
dengan apache
.
Perintah ini akan meminta Anda untuk memasukkan jalur .ini
file, jadi masukkan /etc/letsencrypt/cloudflare.ini
dan tekan tombol Enter.
Setelah sertifikat SSL diperoleh dan diinstal di file konfigurasi server web. Anda harus membuatnya mendengarkan pada 127.0.0.1:443 atau 127.0.0.0.2:443. Misalnya, jika Anda menggunakan Nginx, cari
listen 443 ssl
Dan ubah menjadi
listen 127.0.0.1:443 ssl http2
Juga, ubah port 80 menjadi
listen 127.0.0.1:80;
Simpan dan tutup file. Kemudian restart server web Anda.
Kesalahan Umum
1 Nama Domain Salah
Jika Anda memiliki beberapa host virtual Nginx di server, dan saat Anda mengetik satu nama domain, browser web membawa Anda ke nama domain lain yang dihosting di server yang sama, bisa jadi salah satu nama file host virtual Nginx Anda tidak berakhir dengan .conf
ekstensi nama file, jadi Nginx tidak memuat host virtual ini. Mungkin juga Anda telah menetapkan catatan AAAA untuk nama domain, tetapi Anda tidak mengonfigurasi Nginx untuk melayani nama domain di IPv6.
Hal di atas juga berlaku untuk server web Apache.
2 Pelanggaran Protokol Jaringan
Jika Anda mengatur send-proxy-v2
header di HAProxy, tetapi tidak mengaktifkan proxy_protocol
di Nginx atau Apache, maka website Anda akan menampilkan error berikut.
The site has experienced a network protocol violation that cannot be repaired.
Ingatlah untuk me-restart Nginx/Apache setelah membuat perubahan pada file konfigurasi.
3 PR_CONNECT_RESET_ERROR
Jika Anda mengaktifkan proxy_protocol
di Nginx atau Apache, tetapi tidak menyetel send-proxy-v2
header di HAProxy, maka situs web Anda akan menampilkan kesalahan ini.
secure connection failed. PR_CONNECT_RESET_ERROR
Dan Anda akan menemukan pesan kesalahan berikut di log kesalahan Nginx atau Apache.
broken header while reading PROXY protocol
Ingatlah untuk me-restart Nginx/Apache setelah membuat perubahan pada file konfigurasi.
Perhatikan juga bahwa jika Anda mengaktifkan proxy protocol
dalam satu file host virtual Apache/Nginx, maka file tersebut juga secara implisit diaktifkan untuk semua host virtual lainnya. Dan saya belum menemukan cara untuk menonaktifkan proxy_protocol
untuk host virtual individu. Karena Anda menjalankan Apache dan Nginx di server yang sama, solusinya adalah Anda hanya mengaktifkan protokol proxy di Nginx dan tidak mengaktifkannya di Apache. Jika host virtual tidak perlu mendapatkan alamat IP asli klien, konfigurasikan untuk menggunakan Apache.
Perbarui :Terpikir oleh saya bahwa Anda dapat mengatur host virtual Apache/Nginx baru di alamat loopback lain seperti 127.0.0.4. Dengan cara ini, host virtual baru tidak akan mengaktifkan protokol proxy.
4 PR_END_OF_FILE_ERROR
Jika Anda mengaktifkan protokol proxy di Apache/Nginx, tetapi Anda mencoba mengakses virtual host secara langsung (melewati HAProxy), maka Anda akan melihat kesalahan berikut.
PR_END_OF_FILE_ERROR
5 SSL_ERROR_SYSCALL
Jika Anda menggunakan perintah curl:
curl -I https://example.com
Dan Anda mengalami kesalahan berikut
curl: (35) OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to example.com:443
Mungkin karena Anda tidak menyetel definisi backend untuk domain ini.