Let's Go بهبودهای سرور و امنیت › تنظیمات HTTPS
قبلی · فهرست · بعدی
فصل 9.5.

پیکربندی تنظیمات HTTPS (Configuring HTTPS Settings)

در این بخش، نحوه پیکربندی تنظیمات HTTPS (HTTPS Settings Configuration) را بررسی می‌کنیم. این شامل تنظیمات امنیتی (Security Settings) و بهینه‌سازی عملکرد (Performance Optimization) می‌شود.

برای شروع، بیایید پیکربندی TLS (TLS Configuration) را در کد برنامه (Application Code) خود اضافه کنیم:

Go تنظیمات پیش‌فرض خوبی برای سرور HTTPS خود دارد، اما می‌توان نحوه عملکرد سرور را بهینه و سفارشی کرد.

یکی از تغییراتی که تقریباً همیشه ایده خوبی است، محدود کردن منحنی‌های بیضوی است که می‌توانند در طول دست دادن TLS استفاده شوند. Go از چند منحنی بیضوی پشتیبانی می‌کند، اما از نسخه Go 1.23 تنها tls.CurveP256 و tls.X25519 پیاده‌سازی‌های اسمبلی دارند. بقیه بسیار پردازش‌بر هستند، بنابراین حذف آنها کمک می‌کند تا سرور ما تحت بارهای سنگین عملکرد خوبی داشته باشد.

برای انجام این تغییر، می‌توانیم یک ساختار tls.Config حاوی تنظیمات TLS غیرپیش‌فرض خود ایجاد کنیم و آن را به ساختار http.Server خود اضافه کنیم قبل از اینکه سرور را شروع کنیم.

من نشان خواهم داد:

File: cmd/web/main.go
package main

import (
    "crypto/tls" // New import
    "database/sql"
    "flag"
    "html/template"
    "log/slog"
    "net/http"
    "os"
    "time"

    "snippetbox.alexedwards.net/internal/models"

    "github.com/alexedwards/scs/mysqlstore"
    "github.com/alexedwards/scs/v2"
    "github.com/go-playground/form/v4"
    _ "github.com/go-sql-driver/mysql"
)

...

func main() {
    ...

    app := &application{
        logger:         logger,
        snippets:       &models.SnippetModel{DB: db},
        templateCache:  templateCache,
        formDecoder:    formDecoder,
        sessionManager: sessionManager,
    }

    // Initialize a tls.Config struct to hold the non-default TLS settings we
    // want the server to use. In this case the only thing that we're changing
    // is the curve preferences value, so that only elliptic curves with
    // assembly implementations are used.
    tlsConfig := &tls.Config{
        CurvePreferences: []tls.CurveID{tls.X25519, tls.CurveP256},
    }

    // Set the server's TLSConfig field to use the tlsConfig variable we just
    // created.
    srv := &http.Server{
        Addr:      *addr,
        Handler:   app.routes(),
        ErrorLog:  slog.NewLogLogger(logger.Handler(), slog.LevelError),
        TLSConfig: tlsConfig,
    }

    logger.Info("starting server", "addr", srv.Addr)

    err = srv.ListenAndServeTLS("./tls/cert.pem", "./tls/key.pem")
    logger.Error(err.Error())
    os.Exit(1)
}

...

اطلاعات اضافی

نسخه‌های TLS

به طور پیش‌فرض، سرور HTTPS Go برای پشتیبانی از TLS 1.2 و 1.3 پیکربندی شده است. می‌توانید این را سفارشی کنید و حداقل و حداکثر نسخه‌های TLS را با استفاده از فیلدهای tls.Config.MinVersion و MaxVersion و ثابت‌های نسخه‌های TLS در بسته crypto/tls تغییر دهید.

برای مثال، اگر می‌خواهید سرور فقط از نسخه‌های TLS 1.0 تا 1.2 پشتیبانی کند، می‌توانید از پیکربندی زیر استفاده کنید:

tlsConfig := &tls.Config{
    MinVersion: tls.VersionTLS10,
    MaxVersion: tls.VersionTLS12,
}

مجموعه‌های رمزنگاری

مجموعه‌های رمزنگاری که Go پشتیبانی می‌کند نیز در ثابت‌های بسته crypto/tls تعریف شده‌اند.

با این حال، برخی از این مجموعه‌های رمزنگاری (به طور خاص، مجموعه‌های رمزنگاری که از Perfect Forward Secrecy پشتیبانی نمی‌کنند، یا از RC4، 3DES یا CBC_SHA256 استفاده می‌کنند) ضعیف در نظر گرفته می‌شوند و به طور پیش‌فرض توسط سرور HTTPS Go استفاده نمی‌شوند. از نسخه Go 1.23، مجموعه‌های رمزنگاری که به طور پیش‌فرض توسط سرور HTTPS Go استفاده می‌شوند عبارتند از:

TLS_AES_128_GCM_SHA256                          // TLS 1.3 connections only
TLS_AES_256_GCM_SHA384                          // TLS 1.3 connections only
TLS_CHACHA20_POLY1305_SHA256                    // TLS 1.3 connections only

TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256         // TLS 1.2 connections only
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384         // TLS 1.2 connections only
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256           // TLS 1.2 connections only
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384           // TLS 1.2 connections only
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256     // TLS 1.2 connections only
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256   // TLS 1.2 connections only

TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA            // TLS 1.0, 1.1 and 1.2 connections
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA            // TLS 1.0, 1.1 and 1.2 connections
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA              // TLS 1.0, 1.1 and 1.2 connections
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA              // TLS 1.0, 1.1 and 1.2 connections

اگر می‌خواهید مجموعه‌های رمزنگاری استفاده شده توسط سرور HTTPS Go را تغییر دهید — یا با اضافه کردن مجموعه‌های رمزنگاری ضعیفی که به طور پیش‌فرض استفاده نمی‌شوند، یا حذف برخی از رمزهایی که به طور پیش‌فرض استفاده می‌شوند — می‌توانید این کار را از طریق فیلد tls.Config.CipherSuites انجام دهید.

برای مثال، اگر می‌خواهید از لیست پیش‌فرض رمزها استفاده کنید اما با حذف رمزهای CBC، می‌توانید tls.Config خود را به این صورت پیکربندی کنید:

tlsConfig := &tls.Config{
    CipherSuites: []uint16{
        tls.TLS_AES_128_GCM_SHA256,
        tls.TLS_AES_256_GCM_SHA384,
        tls.TLS_CHACHA20_POLY1305_SHA256,
        tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
        tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
        tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
        tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
        tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
        tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
    },
}

Go به طور خودکار انتخاب می‌کند کدام از این مجموعه‌های رمزنگاری در زمان اجرا استفاده شود بر اساس امنیت رمز، عملکرد و پشتیبانی سخت‌افزار مشتری/سرور.

همچنین مهم (و جالب) است که توجه داشته باشید که اگر یک اتصال TLS 1.3 مذاکره شود، tls.Config.CipherSuites نادیده گرفته می‌شود. دلیل این امر این است که همه مجموعه‌های رمزنگاری که Go برای اتصالات TLS 1.3 پشتیبانی می‌کند به عنوان ایمن در نظر گرفته می‌شوند، بنابراین ارائه مکانیزمی برای پیکربندی آنها چندان منطقی نیست.

به طور اساسی، استفاده از tls.Config.CipherSuites برای تنظیم یک لیست سفارشی از مجموعه‌های رمزنگاری پشتیبانی شده فقط بر اتصالات TLS 1.0-1.2 تأثیر می‌گذارد. بنابراین، در مثال بالا، در واقع نیازی به شامل کردن رمزهای خاص TLS 1.3 نیست و می‌توان آن را به این صورت ساده کرد:

tlsConfig := &tls.Config{
    CipherSuites: []uint16{
        tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
        tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
        tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
        tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
        tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
        tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
    },
}

واژه‌نامه اصطلاحات فنی

اصطلاح فارسی معادل انگلیسی توضیح
پیکربندی تنظیمات HTTPS HTTPS Settings Configuration تنظیم پارامترهای ارتباط امن
تنظیمات امنیتی Security Settings پارامترهای مربوط به امنیت
بهینه‌سازی عملکرد Performance Optimization بهبود کارایی سیستم
پیکربندی TLS TLS Configuration تنظیمات پروتکل امنیتی
کد برنامه Application Code کد منبع برنامه
نسخه TLS TLS Version نسخه پروتکل امنیتی
رمزنگاری Encryption کدگذاری اطلاعات
امنیت اتصال Connection Security حفاظت از ارتباطات
بهینه‌سازی منابع Resource Optimization استفاده بهینه از منابع
پروتکل‌های امن Secure Protocols پروتکل‌های ارتباطی امن