Tampaknya tugas menerapkan frontend untuk AWS pada nginx kedengarannya seperti kasus khas untuk StackOverflow - setelah semua, tidak ada masalah dengan proksi file dari S3? Bahkan, ternyata solusi yang sudah jadi tidak mudah ditemukan, dan artikel ini harus memperbaiki situasi ini.

Mengapa Anda membutuhkan ini?
- Kontrol akses ke file menggunakan nginx - relevan untuk konsep IaC (infrastruktur sebagai kode). Semua perubahan yang terkait dengan akses akan dilakukan hanya di konfigurasi yang ada di proyek.
- Jika Anda memberikan file melalui nginx Anda, Anda bisa menyimpannya dan menyimpan permintaan ke S3.
- Proxy semacam itu akan membantu untuk mengabaikan jenis penyimpanan file untuk instalasi aplikasi yang berbeda (setelah semua, ada solusi lain selain S3).
Kami merumuskan kerangka kerja
- Ember sumber harus pribadi - Anda tidak dapat mengizinkan pengguna anonim untuk mengunduh file langsung dari S3. Jika dalam kasus Anda batasan ini tidak berfungsi, maka cukup gunakan
proxy_pass
dan Anda tidak bisa lagi membaca. - Penyetelan oleh AWS harus dilakukan satu kali dengan dasar “disetel dan lupakan” untuk menyederhanakan operasi.
Kami mencari solusi di dahi
Jika bucket asli Anda bersifat publik, maka tidak ada kesulitan yang mengancam Anda, permintaan proxy untuk S3 dan semuanya akan berfungsi. Jika bersifat pribadi, maka Anda harus mengotentikasi dengan S3. Apa yang ditawarkan oleh rekan-rekan dari Internet:
- Ada contoh penerapan protokol otentikasi menggunakan nginx. Solusinya bagus, tetapi sayangnya, ia dirancang untuk protokol otentikasi yang ketinggalan zaman ( Signature v2 ), yang tidak berfungsi di beberapa pusat data Amazon . Jika Anda mencoba menggunakan solusi ini, misalnya, di Frankfurt, Anda akan mendapatkan kesalahan "Mekanisme otorisasi yang Anda berikan tidak didukung. Silakan gunakan AWS4-HMAC-SHA256 . " Versi protokol yang lebih baru ( Signature v4 ) jauh lebih sulit untuk diimplementasikan, tetapi tidak ada solusi siap pakai untuk nginx dengannya.
- Ada modul pihak ketiga untuk nginx - ngx_aws_auth . Dilihat oleh sumbernya, ia mendukung Signature v4. Namun, proyek ini kelihatannya ditinggalkan: selama lebih dari setahun tidak ada perubahan dalam basis kode, dan ada juga masalah kompatibilitas dengan modul lain yang tidak ditanggapi pengembang. Selain itu, menambahkan modul tambahan ke nginx seringkali merupakan langkah yang menyakitkan.
- Anda dapat menggunakan proksi s3 terpisah, yang sudah cukup banyak ditulis. Secara pribadi, saya menyukai solusi Go - aws-s3-proxy : ia memiliki gambar yang siap pakai dan cukup populer di DockerHub. Tetapi dalam kasus ini, aplikasi akan memperoleh komponen lain dengan masalah potensial.
Terapkan Kebijakan AWS Bucket
AWS, sebagai suatu peraturan, menakuti pengguna baru dengan kerumitan dan volume dokumentasinya. Tetapi jika Anda melihat, Anda mengerti bahwa itu dirancang dengan sangat logis dan fleksibel. Amazon juga menemukan solusi untuk tugas kami -
Kebijakan Bucket S3 . Mekanisme ini memungkinkan Anda untuk membuat aturan otorisasi yang fleksibel untuk bucket berdasarkan parameter klien atau permintaan yang berbeda.
Antarmuka Generator Kebijakan - Pembuat Kebijakan AWSBerikut ini beberapa opsi menarik yang dapat Anda ikat:
- IP (
aws:SourceIp
), - Header referer (
aws:Referer
), - Header Agen-Pengguna (
aws:UserAgent
), - sisanya dijelaskan dalam dokumentasi .
Ikatan IP adalah pilihan yang baik hanya jika aplikasi memiliki tempat tinggal tertentu, dan pada zaman kita jarang. Karena itu, Anda harus terikat pada sesuatu yang lain. Sebagai solusi, saya mengusulkan untuk
membuat User-Agent atau Referer rahasia dan memberikan file hanya kepada pengguna yang mengetahui header rahasia. Inilah yang terlihat seperti kebijakan serupa:
{ "Version": "2012-10-17", "Id": "http custom auth secret", "Statement": [ { "Sid": "Allow requests with my secret.", "Effect": "Allow", "Principal": "*", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::example-bucket-for-habr/*", "Condition": { "StringLike": { "aws:UserAgent": [ "xxxyyyzzz" ] } } } ] }
Sedikit penjelasan:
"Version": "2012-10-17"
adalah dapur AWS internal yang tidak perlu Anda edit;Principal
- siapa yang dipengaruhi oleh aturan ini. Anda dapat menunjukkan bahwa itu hanya berfungsi untuk akun AWS tertentu, tetapi dalam kasus kami harganya "*"
- ini berarti bahwa aturan itu berlaku untuk semua orang, termasuk pengguna anonim;Resource
- ember dan templat ARN (Nama Sumber Daya Amazon) untuk file di dalam ember. Dalam kasus kami, kebijakan ini berlaku untuk semua file yang ada di example-bucket-for-habr
;Condition
- di sini adalah kondisi yang harus konvergen agar kebijakan dapat berfungsi. Dalam kasus kami, kami membandingkan header User-Agent yang telah ditentukan dengan garis xxxyyyzzz
.
Dan di sini adalah bagaimana aturan ini bekerja dari sudut pandang pengguna anonim:
$ curl -I https://s3.eu-central-1.amazonaws.com/example-bucket-for-habr/hello.txt HTTP/1.1 403 Forbidden $ curl -I https://s3.eu-central-1.amazonaws.com/example-bucket-for-habr/hello.txt -H 'User-Agent: xxxyyyzzz' HTTP/1.1 200 OK
Masih
mengkonfigurasi nginx untuk proxy:
location /s3-media/ { limit_except GET { deny all; } set $aws_bucket "example-bucket-for-habr"; set $aws_endpoint "s3.eu-central-1.amazonaws.com:443"; set $aws_custom_secret "xxxyyyzzz"; proxy_set_header User-Agent $aws_custom_secret; rewrite ^/s3-media/(.*)$ /$aws_bucket/$1 break; proxy_buffering off; proxy_pass https://$aws_endpoint; }
Kesimpulan
Secara total, setelah kami menulis kebijakan sederhana untuk bucket, kami berkesempatan untuk mem-proxy file dengan aman menggunakan nginx. Namun, kami tidak terikat oleh IP dan tidak tergantung pada perangkat lunak tambahan.
PS
Baca juga di blog kami: