Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 82 additions & 0 deletions cmd/certificate/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package main

import (
"bytes"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"log"
"math/big"
"net"
"os"
"time"
)

func main() {
// создаём шаблон сертификата
cert := &x509.Certificate{
// указываем уникальный номер сертификата
SerialNumber: big.NewInt(1658),
// заполняем базовую информацию о владельце сертификата
Subject: pkix.Name{
Organization: []string{"Yandex.Praktikum"},
Country: []string{"RU"},
},
// разрешаем использование сертификата для 127.0.0.1 и ::1
IPAddresses: []net.IP{net.IPv4(127, 0, 0, 1), net.IPv6loopback},
// сертификат верен, начиная со времени создания
NotBefore: time.Now(),
// время жизни сертификата — 10 лет
NotAfter: time.Now().AddDate(10, 0, 0),
SubjectKeyId: []byte{1, 2, 3, 4, 6},
// устанавливаем использование ключа для цифровой подписи,
// а также клиентской и серверной авторизации
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
KeyUsage: x509.KeyUsageDigitalSignature,
}

// создаём новый приватный RSA-ключ длиной 4096 бит
// обратите внимание, что для генерации ключа и сертификата
// используется rand.Reader в качестве источника случайных данных
privateKey, err := rsa.GenerateKey(rand.Reader, 4096)
if err != nil {
log.Fatal(err)
}

// создаём сертификат x.509
certBytes, err := x509.CreateCertificate(rand.Reader, cert, cert, &privateKey.PublicKey, privateKey)
if err != nil {
log.Fatal(err)
}

// кодируем сертификат и ключ в формате PEM, который
// используется для хранения и обмена криптографическими ключами
var certPEM bytes.Buffer
err = pem.Encode(&certPEM, &pem.Block{
Type: "CERTIFICATE",
Bytes: certBytes,
})
if err != nil {
log.Fatal(err)
}

var privateKeyPEM bytes.Buffer
err = pem.Encode(&privateKeyPEM, &pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: x509.MarshalPKCS1PrivateKey(privateKey),
})
if err != nil {
log.Fatal(err)
}

// Сохраняем сертификат и приватный ключ в файлы cert.pem и private.pem
if err = os.WriteFile("cert.pem", certPEM.Bytes(), 0644); err != nil {
log.Fatal(err)
}

if err = os.WriteFile("key.pem", privateKeyPEM.Bytes(), 0644); err != nil {
log.Fatal(err)
}
}
5 changes: 5 additions & 0 deletions internal/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type App struct {
router *gin.Engine
urlHandler *handler.URLHandler
deleteWorker *worker.DeleteWorker
enableTLS bool
}

// New создаёт и настраивает новое приложение:
Expand Down Expand Up @@ -152,6 +153,7 @@ func New() (*App, error) {
router: router,
urlHandler: urlHandler,
deleteWorker: deleteWorker,
enableTLS: cfg.Enable_HTTPS,
}, nil
}

Expand Down Expand Up @@ -201,6 +203,9 @@ func (a *App) SetupRoutes() {

// Run запускает HTTP-сервер.
func (a *App) Run() error {
if a.enableTLS {
return a.server.ListenAndServeTLS("cert.pem", "key.pem")
}
return a.server.ListenAndServe()
}

Expand Down
15 changes: 14 additions & 1 deletion internal/config/flag/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type ServerConfig struct {
SecretKey string `env:"SECRET_KEY"`
AuditFile string `env:"AUDIT_FILE"`
AuditURL string `env:"AUDIT_URL"`
Enable_HTTPS bool `env:"ENABLE_HTTPS"`
}

var (
Expand All @@ -34,6 +35,7 @@ var (
secretKey *string
auditFile *string
auditURL *string
enableHTTPS *bool
flagsOnce sync.Once
)

Expand All @@ -45,9 +47,10 @@ func initFlags() {
dsnValue = flag.String("d", "", "database DSN")
deleteWorkerCount = flag.Int("w", 2, "number of delete worker channels")
deleteChannelSize = flag.Int("c", 1000, "size of each delete channel buffer")
secretKey = flag.String("s", "my-super-secret-key-change-in-production", "secret key for signing cookies")
secretKey = flag.String("sk", "my-super-secret-key-change-in-production", "secret key for signing cookies")
auditFile = flag.String("audit-file", "", "path to audit log file")
auditURL = flag.String("audit-url", "", "URL of remote audit server")
enableHTTPS = flag.Bool("s", false, "enable HTTPS")
}

// NewServerConfig создаёт конфигурацию, читая флаги и переменные окружения.
Expand Down Expand Up @@ -128,6 +131,16 @@ func NewServerConfig() *ServerConfig {
cfg.AuditURL = *auditURL
}

if envEnableHTTPS, ok := os.LookupEnv("ENABLE_HTTPS"); ok {
if val, err := strconv.ParseBool(envEnableHTTPS); err == nil {
cfg.Enable_HTTPS = val
} else {
cfg.Enable_HTTPS = *enableHTTPS
}
} else {
cfg.Enable_HTTPS = *enableHTTPS
}

return cfg
}

Expand Down
Loading