init
This commit is contained in:
commit
23c7133fa9
33 files changed
+2896
No files matched your search
@@ -0,0 +1,123 @@
|
||||
// Command ssh-access-tui is a terminal UI for administering a Linux jump
|
||||
// host: creating jump/forward-only user accounts, scoping each one's
|
||||
// allowed destination hosts via SSH group membership, exporting encrypted
|
||||
// key/config archives for delivery, locking departed users, and viewing who
|
||||
// is currently connected.
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
|
||||
"ssh-access-tui/internal/audit"
|
||||
"ssh-access-tui/internal/config"
|
||||
"ssh-access-tui/internal/store"
|
||||
"ssh-access-tui/internal/sysadm"
|
||||
"ssh-access-tui/internal/ui"
|
||||
)
|
||||
|
||||
const defaultConfigPath = "/etc/ssh-access-tui/config.yaml"
|
||||
|
||||
func main() {
|
||||
configPath := flag.String("config", defaultConfigPath, "путь к конфигурации")
|
||||
flag.Parse()
|
||||
|
||||
args := flag.Args()
|
||||
sub := ""
|
||||
if len(args) > 0 {
|
||||
sub = args[0]
|
||||
}
|
||||
|
||||
cfg, err := config.Load(*configPath)
|
||||
if err != nil {
|
||||
fatal(err)
|
||||
}
|
||||
|
||||
switch sub {
|
||||
case "install":
|
||||
runInstall(*configPath, cfg)
|
||||
case "audit-tail":
|
||||
if err := audit.TailJournal(cfg.AuditLog); err != nil {
|
||||
fatal(err)
|
||||
}
|
||||
default:
|
||||
runTUI(cfg)
|
||||
}
|
||||
}
|
||||
|
||||
func runTUI(cfg config.Config) {
|
||||
if err := sysadm.RequireRoot(); err != nil {
|
||||
fatal(fmt.Errorf("%w (управление пользователями и authorized_keys требует привилегий root)", err))
|
||||
}
|
||||
if cfg.JumpHost == "" {
|
||||
fatal(fmt.Errorf("jump_host не задан в %s — укажите публичный адрес этого хоста для генерации клиентских конфигов", defaultConfigPath))
|
||||
}
|
||||
st, err := store.New(cfg.StateDir)
|
||||
if err != nil {
|
||||
fatal(err)
|
||||
}
|
||||
p := tea.NewProgram(ui.New(cfg, st), tea.WithAltScreen())
|
||||
if _, err := p.Run(); err != nil {
|
||||
fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func runInstall(configPath string, cfg config.Config) {
|
||||
if err := sysadm.RequireRoot(); err != nil {
|
||||
fatal(err)
|
||||
}
|
||||
if err := os.MkdirAll(cfg.StateDir, 0o750); err != nil {
|
||||
fatal(err)
|
||||
}
|
||||
if err := os.MkdirAll(cfg.ExportDir, 0o750); err != nil {
|
||||
fatal(err)
|
||||
}
|
||||
if err := os.MkdirAll(cfg.ScratchDir, 0o700); err != nil {
|
||||
fatal(err)
|
||||
}
|
||||
if err := os.MkdirAll(dirOf(cfg.AuditLog), 0o750); err != nil {
|
||||
fatal(err)
|
||||
}
|
||||
if err := os.MkdirAll(dirOf(configPath), 0o755); err != nil {
|
||||
fatal(err)
|
||||
}
|
||||
if cfg.JumpHost == "" {
|
||||
fmt.Print("Публичный адрес этого jump-хоста (как к нему подключаются пользователи): ")
|
||||
fmt.Scanln(&cfg.JumpHost)
|
||||
}
|
||||
if err := config.Save(configPath, cfg); err != nil {
|
||||
fatal(err)
|
||||
}
|
||||
if err := sysadm.EnsureJumpGroup(); err != nil {
|
||||
fatal(err)
|
||||
}
|
||||
if err := sysadm.InstallSSHDConfig(); err != nil {
|
||||
fatal(err)
|
||||
}
|
||||
if !sysadm.DropInIncluded() {
|
||||
fmt.Println("ВНИМАНИЕ: /etc/ssh/sshd_config не похож на включающий sshd_config.d/*.conf.")
|
||||
fmt.Println("Добавьте туда вручную строку: Include /etc/ssh/sshd_config.d/*.conf")
|
||||
}
|
||||
fmt.Println("Установка завершена.")
|
||||
fmt.Printf("Конфигурация: %s\n", configPath)
|
||||
fmt.Printf("Состояние (git-репозиторий): %s\n", cfg.StateDir)
|
||||
fmt.Printf("Архивы экспорта: %s\n", cfg.ExportDir)
|
||||
fmt.Println("Не забудьте включить фоновый сборщик журнала: systemctl enable --now ssh-access-tui-audit.service")
|
||||
}
|
||||
|
||||
func dirOf(path string) string {
|
||||
for i := len(path) - 1; i >= 0; i-- {
|
||||
if path[i] == '/' {
|
||||
return path[:i]
|
||||
}
|
||||
}
|
||||
return "."
|
||||
}
|
||||
|
||||
func fatal(err error) {
|
||||
fmt.Fprintln(os.Stderr, "ssh-access-tui:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
Reference in new issue
Block a user