Tampil di HN: Hosting situs web menggunakan server web C
(github.com/cozis)- BlogTech adalah toolkit berbasis C untuk mengelola situs web skala kecil hingga menengah, menyediakan HTTPS, virtual host, manajemen sertifikat otomatis berbasis ACME, dan klien untuk manajemen server jarak jauh
- Saat ini masih dalam tahap pengujian; versi
0.4.xtelah digunakan untuk beroperasi selama beberapa minggu, tetapi tidak dipresentasikan sebagai rilis stabil - Server berjalan di Linux dan Windows, tetapi HTTPS hanya didukung di Linux; di Windows, baik klien maupun server hanya dapat menggunakan HTTP
- Manajemen file jarak jauh ditangani dengan
--put,--get,--delete, dan permintaan yang mengubah resource diautentikasi dengan tanda tangan HMAC/SHA256 berbasis shared secret key - Di lingkungan produksi, diperlukan server HTTP pada port 80 dan record DNS domain; jika ACME diaktifkan, file sertifikat dan private key dibuat otomatis, dan kesalahan dicatat di
acme.log
Tujuan dan status BlogTech saat ini
- BlogTech adalah toolkit untuk mengelola situs web skala kecil hingga menengah
- Fitur yang didukung adalah sebagai berikut
-
HTTPS
-
Virtual host
- Manajemen sertifikat otomatis melalui ACME
- Klien untuk manajemen server jarak jauh
- Masih dalam tahap pengujian
- Ada contoh versi
0.4.xyang berhasil melayanihttps://coz.is/selama beberapa minggu - Versi lama satu file ada di branch
single_file
-
Build dan eksekusi dasar
- BlogTech berjalan di Linux dan Windows
- Build Linux memerlukan library pengembangan OpenSSL dan
gcc - Build Windows memerlukan
clang
- Build Linux memerlukan library pengembangan OpenSSL dan
- Build dilakukan dengan skrip khusus platform
- Linux:
./build.sh - Windows:
.\build.bat
- Linux:
- Hasil build adalah sebagai berikut
- Linux:
blogtech - Windows:
blogtech.exe
- Linux:
- Di Linux, instalasi dapat dilakukan dengan
./install.sh - Contoh menjalankan server dasar adalah membuat direktori
docrootdan menentukan--serve,--document-root=docroot,--skip-auth-check - Server HTTP dasar mendengarkan di
127.0.0.1:8080dan menyajikan konten daridocroot - Jika
docrootkosong, akses kehttp://127.0.0.1:8080/akan mengembalikan 404
Manajemen file jarak jauh dan autentikasi
- BlogTech dapat mengunggah file ke server dalam mode klien
- Mengunggah file dengan
--put - Mengunduh file jarak jauh dengan
--get - Menghapus file jarak jauh dengan
--delete
- Mengunggah file dengan
- Meski klien dan server dijalankan di mesin yang sama, maupun terhadap server di mesin jarak jauh, cara kerjanya sama
- Permintaan yang mengubah resource ditandatangani secara digital dengan tanda tangan HMAC/SHA256
- Klien dan server harus berbagi secret key yang sama, dan secara konvensi disimpan dalam file
admin.pwd - File kata sandi ditentukan dengan opsi
--auth-password-file - Jika file kata sandi tidak ada, semua permintaan yang memerlukan autentikasi akan ditolak
- Kata sandi kosong juga ditolak
- Selama pengembangan,
--skip-auth-checkdapat digunakan untuk memperlakukan semua permintaan sebagai terautentikasi- Jika opsi ini digunakan,
--auth-password-fileakan diabaikan meskipun ditentukan - Harus digunakan dengan hati-hati
- Jika opsi ini digunakan,
-
Header autentikasi dan kondisi pengiriman ulang
- Permintaan HTTP yang terautentikasi menyertakan header
X-BlogTech- X-BlogTech-Nonce: token yang dipilih secara acak oleh klienX-BlogTech-Timestamp: UNIX timestamp saat permintaan pertama kali ditandatanganiX-BlogTech-Expire: waktu dalam satuan detik sejak saat penandatanganan selama permintaan validX-BlogTech-Signature: nilai HMAC dari informasi permintaan yang dienkode dalam Base64- Tanda tangan diperoleh dengan membuat string permintaan yang dinormalisasi, lalu menghitung HMAC/SHA256 menggunakan kata sandi autentikasi sebagai key, dan mengenkode hasilnya ke Base64 termasuk padding
- Nonce yang sudah pernah dilihat server disimpan di memori
- Jika server dimuat ulang, nonce sebelumnya akan dilupakan, sehingga permintaan yang belum kedaluwarsa dapat dikirim ulang
- Permintaan HTTP yang terautentikasi menyertakan header
Virtual host dan pemetaan direktori
- BlogTech dapat meng-host beberapa situs web pada server yang sama
- Domain diatur dengan menentukan opsi
--domainbeberapa kali - BlogTech membuat direktori per domain di dalam document root
defaultwebsiteA.comwebsiteB.com
- Permintaan yang masuk ke host tertentu mengacu pada direktori yang terhubung dengan host tersebut
- Permintaan yang tidak terhubung ke folder tertentu mengacu pada direktori default
- Dalam contoh, file yang diunggah ke
websiteA.com,websiteB.com,other.commasing-masing disimpan di direktori domain atau direktoridefault
HTTPS dan pengaturan sertifikat
- HTTPS hanya didukung di Linux
- Ini karena library HTTP yang mendasarinya, cHTTP, mengimplementasikan HTTPS dengan OpenSSL
- Di Windows, baik klien maupun server hanya dapat menggunakan HTTP
- Untuk mengaktifkan HTTPS, opsi berikut diperlukan
--https-enabled--cert-file--cert-key-file
- Alamat listen HTTPS default adalah
127.0.0.1:8443 - Alamat listen dan port dapat diubah dengan opsi berikut
--https-addr=<addr>--https-port=<port>
- Selama pengembangan, sertifikat self-signed dapat dibuat dengan perintah OpenSSL
- Browser tidak mengizinkan penelusuran server HTTPS yang menggunakan sertifikat self-signed
- cURL harus menggunakan flag
--insecureagar dapat mengakses server dengan sertifikat self-signed - Jika diperlukan beberapa sertifikat,
--extra-certdapat diberikan sebagai tambahan- Sertifikat default disediakan melalui
--cert-file,--cert-key-file - Sertifikat tambahan digunakan saat klien meminta domain tertentu
- Sertifikat default disediakan melalui
- Opsi command line yang panjang dapat dipindahkan ke file konfigurasi
Penerbitan sertifikat otomatis berbasis ACME
- Protokol ACME memungkinkan web server secara otomatis meminta penerbitan sertifikat ke certificate authority
- BlogTech mendukung alur memulai mode HTTPS tanpa sertifikat, lalu sertifikat dibuat
- Di lingkungan produksi, syarat berikut diperlukan
- Menjalankan server HTTP pada port 80
- Membuat record DNS yang menghubungkan domain dengan mesin tempat server berjalan
- ACME diaktifkan dengan menentukan
--acme-enabledbersama opsi HTTPS - Berbeda dengan mode HTTPS biasa, dalam mode ACME sertifikat diharapkan belum ada
- Untuk membuat sertifikat, nilai berikut diperlukan
--acme-domain--acme-email--acme-country--acme-organization--acme-agree-tos
- Jika berhasil diproses, file berikut dibuat
acme_key.pem: private key yang terhubung dengan akun ACMEcert.pem: sertifikat yang diterbitkan atau file yang ditentukan dengan--cert-filekey.pem: private key yang terhubung dengan sertifikat atau file yang ditentukan dengan--cert-key-file
- Jika terjadi kesalahan, pesan dicatat di
acme.log - Jika
--acme-domainditentukan beberapa kali, beberapa domain dapat diproses dengan ACME - Sertifikat hasilnya mencakup semua domain yang ditentukan
Pengujian klien ACME
- Untuk menguji klien ACME di Linux, Anda harus memasang Docker dan meng-clone Pebble ACME server
- Pada
docker-compose.yml, tambahkan entriextra_hostsyang menghubungkan domain pengujian kehost-gateway - Pada
/etc/hosts, petakan domain pengujian ke127.0.0.1 - Pebble dijalankan dengan
docker compose up - BlogTech menjalankan instance pengujian dengan
./blogtech -s --config=misc/pebble_blogtech.conf - Interaksi dengan server ACME dicetak ke stdout
- Jika berhasil,
acme_key.pem,cert.pem,key.pemdibuat - Pengujian perpanjangan sertifikat dapat dilakukan dengan mengubah nilai
validityPerioddipebble/test/config/pebble-config.json - Dengan opsi
--acme-force-renewal-period=<maximum duration in ms>, BlogTech dapat diinstruksikan untuk memperpanjang sertifikat meskipun belum kedaluwarsa
File konfigurasi dan pemuatan otomatis
- BlogTech dapat memindahkan jumlah argumen command line berapa pun ke file konfigurasi
- Misalnya, opsi terkait HTTPS dan ACME dapat ditulis di
blogtech_server.conf, lalu dijalankan dengan--config=blogtech_server.conf - Jika nama file konfigurasi persis
blogtech.conf, BlogTech akan memuatnya secara otomatis - Dalam kasus ini, dapat dijalankan seperti
./blogtech --serve - Untuk mengabaikan pemuatan file konfigurasi implisit, gunakan
--no-config
Log crash dan daemon systemd
- Jika BlogTech crash dalam mode server, file
crash.binakan dibuat - Saat server berikutnya dimulai,
crash.bindikonversi menjadicrash.log, stack trace yang dapat dibaca manusia - Proses mengubah alamat menjadi nama simbol atau nomor baris mungkin agak tidak stabil
- BlogTech dapat dipasang sebagai daemon systemd
- Contoh
blogtech.servicemenjalankan/root/blogtech/blogtech -s, memulai ulang saat gagal, dan mengatur direktori kerja ke/root/blogtech/ - Opsi server dimuat otomatis dari
/root/blogtech/blogtech.conf - Setelah menyalin file service ke
/etc/systemd/system/, aktifkan dan mulai dengan perintah berikutsystemctl daemon-reloadsystemctl enable blogtechsystemctl start blogtech
- Manajemen service dilakukan dengan
systemctl start,systemctl stop,systemctl restart,journalctl -u blogtech
1 komentar
Komentar Hacker News
Bagian “tidak perlu reverse proxy” selalu membuat saya heran
Kalau tidak ada alasan khusus mengapa reverse proxy membantu, saya biasa mengekspos aplikasi Jetty embedded langsung ke internet tanpa lapisan depan, dan tidak ada masalah
Orang infrastruktur atau keamanan bertanya mengapa tidak menaruh nginx di depannya, tetapi saat ditanya alasannya, mereka hanya bicara samar tentang keamanan atau performa tanpa rincian. Jawaban paling spesifik yang pernah saya dengar adalah slow loris, tetapi itu sudah lama bukan masalah besar
Saya penasaran apakah reverse proxy secara kolektif sudah menjadi cargo cult, atau saya melewatkan alasan bagus yang berlaku umum
Secara keseluruhan, ini melindungi server asal dan membuatnya hanya menerima trafik yang relevan. Saat menyediakan domain kustom untuk pelanggan pun, DNS pelanggan menunjuk ke reverse proxy, bukan server asal, jadi jika perlu mengganti server asal, kita tidak perlu khawatir pelanggan harus mengubah DNS
Masing-masing berjalan di port berbeda, tetapi saya ingin semuanya bisa diakses publik lewat URL yang berbeda-beda dan hanya ingin mengekspos port 443 ke internet
Saya juga ingin sertifikat TLS tiap domain diperbarui otomatis. Untuk kebutuhan pertama reverse proxy diperlukan, dan Caddy melakukan keduanya
Jika hanya mengoperasikan satu server dan server itu juga melakukan terminasi TLS, reverse proxy tidak wajib diperlukan
Karena nantinya terminasi TLS, penulisan ulang URL, dan pekerjaan lain bisa ditambahkan tanpa banyak repot, saya jadi memakainya sebagai kebiasaan, dan sejauh ini kebiasaan itu terbayar
Dari sisi keamanan, saya ingin seluruh sistem memakai kode sesedikit mungkin dan sistem operasi yang tangguh. Aplikasi bertipe proxy bisa jauh lebih sederhana daripada server web/aplikasi, dan juga bisa memfilter trafik masuk, memvalidasi input, atau mengubahnya menjadi bentuk yang lebih aman dan cepat untuk di-parse. Proxy itu juga bisa dijalankan di sistem operasi yang sulit diserang seperti OpenBSD, GenodeOS, atau INTEGRITY-178B
Dari sisi ketersediaan, sering kali lebih aman menaruh load balancing, monitoring, dan recovery di sistem seperti ini, karena server aplikasi bisa lebih sering mati
Dari sisi performa, keunggulannya pertama-tama adalah aplikasi yang sederhana dan terfokus bisa dioptimalkan tinggi. Setelah itu, kompresi atau enkripsi bisa dipercepat dengan akselerator CPU atau perangkat keras PCI, yang sering disebut offloading. Konfigurasi yang paling hemat biaya adalah banyak server serbaguna mendapatkan manfaat dari sedikit server offloading mahal. Sebagian juga mengurangi penggunaan sumber daya mahal dengan load balancing yang mengirim trafik masuk ke server yang paling mampu menanganinya
Dalam konfigurasi minimal memang tidak perlu, tetapi bahkan pada lingkungan operasi satu host, itu memungkinkan rolling release, kompresi, TLS, penyajian file statis yang cepat, dan potensi A/B testing
Lapisan tidak langsung antara request dan server bisa cukup berguna
Keren. Saya juga dulu pernah menulis web server C sendiri, dan source-nya ada di bawah. Sempat dipakai menjalankan situs web komersial juga
Menakjubkan betapa kecil dan ringannya HTTP/1.1 web server bisa dibuat. Situs komersial itu berjalan di mesin dengan RAM 128MB dan 1 CPU, dan secara rutin melayani banyak sekolah di Inggris sebagai sistem chat interaktif berbasis web yang closed source. Namun itu cerita 20 tahun lalu, saat internet belum sebermusuhan sekarang
Artikel itu mengatakan bot berperan sebagai fuzzer yang bagus, tetapi menurut saya tetap sebaiknya melakukan sedikit fuzzing sungguhan
http://git.annexia.org/?p=rws.git;a=tree
Dependensi:
http://git.annexia.org/?p=c2lib.git;a=tree
http://git.annexia.org/?p=pthrlib.git;a=tree
Situs web saya https://blessed.rs berjalan di VM terkecil yang bisa saya temukan, dengan RAM 256MB, tetapi biasanya hanya memakai sekitar 60MB
Hal yang benar-benar mengejutkan adalah fork di Linux menjadi sangat cepat jika memory map hanya terdiri dari lima halaman 4KB
Ini proyek kecil yang saya mulai di waktu luang untuk bersenang-senang, dan saya pikir orang-orang di sini akan menyukainya :)
Luar biasa. Sejak dulu saya selalu berpikir bahwa menjalankan layanan minimal dengan memakai API sistem pada level serendah ini benar-benar memuaskan, dan sekarang pun masih begitu
Rasanya nyaris seperti sihir, apalagi saat melihatnya menangani trafik sungguhan. Agak mengejutkan juga bahwa
poll()biasa bisa menghasilkan angka seperti itu, tapi mungkin karena sudah lama saya tidak menangani event atau benchmark di level tersebutSaya juga suka pendekatan fungsi per koneksi beserta struct terkait, pengelolaan koneksi dengan array, dan array file descriptor untuk
poll. Itu mengingatkan saya pada cara kerja berbagai paket open source yang dikenal punya throughput tinggi, seperti nginx, Redis, dan memcachedSaya jadi berpikir semua orang sebaiknya mengetahui dan mencoba sebanyak mungkin bahasa, baik bahasa pemrograman maupun bahasa alami. Berpikir dalam suatu bahasa adalah pengalaman yang unik. Konteks yang berbeda membuat semuanya terasa berbeda, dan bahkan ketika pada akhirnya melakukan hal yang mirip, sudut pandangnya berubah
Misalnya, untuk benar-benar memahami esensi Linux atau Git, kita perlu berbicara dalam bahasa itu dan memahami nuansa yang biasanya hilang dalam terjemahan. Mirip seperti untuk memahami makna subjektif sebenarnya dari kata “hutan” dalam bahasa Rusia, kita perlu berbicara dan memahami bahasa Rusia
Konteks mengubah sudut pandang, dan kadang mengubah segalanya
Saya juga terkejut bahwa
poll()biasa bisa bertahan sejauh itu. Saya kira suatu saat harus pindah keepoll, tapipoll()bekerja dengan sangat baikTidak ada yang baru di bawah matahari
Ini juga mungkin menarik: https://news.ycombinator.com/item?id=27431910
Per 2024, instance althttpd milik sqlite.org menangani lebih dari 500 ribu request HTTP per hari, sekitar 5–6 per detik, dan menyajikan sekitar 200GB konten per hari, sekitar 18Mbit/s, dari Linode seharga 40 dolar per bulan. Load average mesin ini biasanya berada di sekitar 0,5. Sekitar 19% request HTTP adalah CGI ke beberapa repositori kode sumber Fossil
Jika ingin menulis aplikasi C tetapi merasa tidak nyaman menulis sendiri bagian yang langsung terpapar internet publik, Kore adalah framework yang cukup bagus
Ada fitur bawaan yang praktis seperti manajemen sertifikat ACME, Pgsql, curl, dan WebSocket
Pada dasarnya kita bisa membangun, menjalankan, dan menggabungkan modul, serta memungkinkan mencampur Lua/Python dengan C
https://kore.io/
Akhirnya ada situs web yang tidak mati meski masuk halaman depan
Bukan berarti proyek ini tidak hebat, tetapi kalau hal seperti ini benar-benar penting di lingkungan produksi dan sebagian besar kontennya statis, pakai saja CDN. Performanya hampir selalu akan lebih baik daripada apa pun yang kita tulis sendiri. Hanya saja tidak menyenangkan
Proyeknya rapi dan keren, tapi sepertinya kebanyakan orang akan pergi ke GitHub, bukan ke tautan yang menampilkan halaman web. Apakah saya melewatkan sesuatu?
Saya suka bagian yang berbunyi, “Saya senang membuat alat saya sendiri, dan saya agak lelah mendengar bahwa semuanya harus teruji di dunia nyata. Jadi kalau mati, lalu kenapa? Bug bisa diperbaiki :^)”
Server HTTP dan HTTPS lengkap hanya dengan 3,4 ribu baris kode C? Jujur saya kira untuk sepenuhnya mematuhi spesifikasi dibutuhkan jauh lebih banyak
Kalau hanya menerima request GET dan menetapkan
Content-Lengthpada respons, itu sudah cukup untuk 99% user agent. MenanganiTransfer-Encodingdan header byte range pun tidak banyak menambah kodeHTTPS hanyalah HTTP di atas soket TLS, dan kalau tidak mengimplementasikan kriptografi sendiri, tingkat abstraksinya memang kurang lebih segitu. Menarik, dan sebenarnya tidak seburuk itu
httpd(8)[1] dari OpenBSD pun saat ini sedikit di bawah 15.000 baris, termasuk dokumentasiJika menghapus beberapa fitur dan membuat beberapa asumsi, saya tidak akan terkejut kalau bisa masuk kisaran 5.000 baris seperti proyek ini
Hasil
$ wc -l *totalnya 14815 baris[1]: https://man.openbsd.org/httpd.8
Tentu saja saya tidak akan menaruhnya di internet publik dan itu hanya mengimplementasikan sebagian sangat kecil dari HTTP/1.1, tetapi ia bekerja dan hanya membutuhkan
mallocsaat inisialisasiSaya teringat presentasi Chaos Communication Congress tentang blog/server web yang ditulis dalam C
Isinya tentang banyak fitur keamanan seperti penyimpanan immutable, penurunan hak akses, dan memastikan blog tidak bisa mengakses sertifikat TLS: https://www.youtube.com/watch?v=TaE28fJVPTk