main.go 2.03 KB
Newer Older
liming6's avatar
liming6 committed
1
2
3
package main

import (
4
	"fmt"
liming6's avatar
liming6 committed
5
6
7
8
9
10
	"log"
	"net"
	"os"
	"os/signal"
	"sync"
	"syscall"
11
12
13

	"github.com/gofrs/flock"
	"github.com/spf13/pflag"
liming6's avatar
liming6 committed
14
15
16
)

var (
17
18
	wg       = sync.WaitGroup{}
	helpFlag = pflag.BoolP("help", "p", false, "show help")
liming6's avatar
liming6 committed
19
20
21
)

func main() {
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
	socketPath := "/tmp/rsyslog.sock"
	pflag.Parse()
	if *helpFlag {
		fmt.Printf("%s: \nObtain SSHD logs from rsyslog, record them, and provide query services.\n", os.Args[0])
		fmt.Printf("You need to forward the sshd logs to the Unix socket(%s) via rsyslog.\n", socketPath)
		fmt.Printf("You can access the Unix socket(%s) to obtain online user information.\n", GIN_SOCK_PATH)
		fmt.Println("such as: curl -s --unix-socket /tmp//tmp/sshd-tool.sock http://localhost/user | jq")
		return
	}

	fileLock := flock.New("/var/lock/sshd-tool.lock", flock.SetPermissions(0644))
	l, err := fileLock.TryLock()
	if err != nil {
		log.Fatalf("error lock file /var/lock/sshd-tool.lock, %v", err)
	}
	if !l {
		log.Fatalf("can't lock /var/lock/sshd-tool.lock, Perhaps an instance is already running.")
	}

liming6's avatar
liming6 committed
41
	InitSSH()
42
	serverListener := InitGin()
liming6's avatar
liming6 committed
43

44
	err = os.RemoveAll(socketPath)
liming6's avatar
liming6 committed
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67

	if err != nil {
		log.Fatalf("error delete %s: %v", socketPath, err)
	}

	conn, err := net.ListenPacket("unixgram", socketPath)

	if err != nil {
		log.Fatalf("listen unix socket %s failed: %s", socketPath, err.Error())
	}
	err = os.Chmod(socketPath, 0666)
	if err != nil {
		log.Fatalf("chmod 666 %s failed: %v", socketPath, err)
	}

	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)

	wg.Add(1)
	go func(wg *sync.WaitGroup) {
		select {
		case <-sigChan:
			conn.Close()
68
			serverListener.Close()
liming6's avatar
liming6 committed
69
			os.Remove(socketPath)
70
71
			os.Remove(GIN_SOCK_PATH)
			fileLock.Unlock()
liming6's avatar
liming6 committed
72
73
		case <-globalCtx.Done():
			conn.Close()
74
			serverListener.Close()
liming6's avatar
liming6 committed
75
			os.Remove(socketPath)
76
77
			os.Remove(GIN_SOCK_PATH)
			fileLock.Unlock()
liming6's avatar
liming6 committed
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
		}
		wg.Done()
	}(&wg)

	buffer := make([]byte, 16384)
	for {
		n, _, err := conn.ReadFrom(buffer)
		if err != nil {
			globalCancelFunc()
			break
		}
		go ParseSSHLog(string(buffer[:n]))
	}
	wg.Wait()
}