Мастер: авто-синхронизация времени (ВНИИФТРИ) и доменные имена сервера

Шаг «Время и сеть»:
- Кнопка «Синхронизировать»: bj сам пробует российские серверы точного
  времени ВНИИФТРИ (мини-SNTP зонд по UDP/123), и только если из сети они
  недоступны — просит указать свой сервер (контроллер домена/маршрутизатор).
  Статус времени берётся из timedatectl (timeSynced), а не из флага шага.
- Поле «Доменное имя сервера»: имена вписываются в самоподписанный сертификат
  (SAN), чтобы интерфейс открывался по имени без предупреждения браузера.
  Сертификат перевыпускается на лету; A-запись заводит админ сети на DNS.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XG3zNMMf2LMoDpXo22mwMX
This commit is contained in:
fontvielle
2026-10-16 15:15:09 +03:00
parent 33861d98d8
commit 2df7b0f54a
4 changed files with 202 additions and 3 deletions
+15 -1
View File
@@ -36,6 +36,10 @@ type HTTPSSettings struct {
// (самоподписанный сертификат bj создаёт сам): пароли не должны идти по сети открытым текстом.
RedirectOff bool `json:"redirect_off,omitempty"`
Custom bool `json:"custom,omitempty"` // загружен сертификат организации (не самоподписанный)
// Hostnames — доменные имена сервера (например, m2m.corp.example.ru). DNS организации
// (контроллер домена) направляет их на bj, а bj вписывает их в самоподписанный сертификат,
// чтобы браузер не ругался на имя. Пусто — только имя хоста и его IP.
Hostnames []string `json:"hostnames,omitempty"`
}
// RedirectOn — браузер с HTTP перенаправляется на HTTPS.
@@ -85,6 +89,7 @@ func ensureSelfSigned(force bool) error {
return err
}
host, ips := localAddrs()
names := uniqStrings(append([]string{pickStr(host, "bj-server"), "localhost", pickStr(host, "bj-server") + ".local"}, customHostnames()...))
serial, _ := rand.Int(rand.Reader, new(big.Int).Lsh(big.NewInt(1), 62))
tpl := &x509.Certificate{
SerialNumber: serial,
@@ -93,7 +98,7 @@ func ensureSelfSigned(force bool) error {
NotAfter: time.Now().AddDate(5, 0, 0),
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
DNSNames: []string{pickStr(host, "bj-server"), "localhost", pickStr(host, "bj-server") + ".local"},
DNSNames: names,
IPAddresses: ips,
}
der, err := x509.CreateCertificate(rand.Reader, tpl, tpl, &key.PublicKey, key)
@@ -206,6 +211,15 @@ func selfSignedStale() bool {
return true
}
}
have := map[string]bool{}
for _, n := range c.DNSNames {
have[strings.ToLower(n)] = true
}
for _, n := range customHostnames() {
if n = strings.ToLower(strings.TrimSpace(n)); n != "" && !have[n] {
return true
}
}
return false
}