captured: use multilisten
This commit is contained in:
parent
c24eefbb51
commit
2b3cf0bf61
@ -7,14 +7,18 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"flag"
|
"flag"
|
||||||
"log"
|
"log"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
"sync"
|
"sync"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"router7/internal/multilisten"
|
||||||
|
|
||||||
|
"github.com/gokrazy/gokrazy"
|
||||||
"github.com/google/gopacket"
|
"github.com/google/gopacket"
|
||||||
"github.com/google/gopacket/layers"
|
"github.com/google/gopacket/layers"
|
||||||
"github.com/google/gopacket/pcapgo"
|
"github.com/google/gopacket/pcapgo"
|
||||||
|
|
||||||
"golang.org/x/sync/errgroup"
|
|
||||||
|
|
||||||
_ "net/http/pprof"
|
_ "net/http/pprof"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -79,23 +83,48 @@ func (prb *packetRingBuffer) packetsLocked() []gopacket.Packet {
|
|||||||
return packets
|
return packets
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var sshListeners = multilisten.NewPool()
|
||||||
|
|
||||||
|
func updateListeners(srv *server) error {
|
||||||
|
hosts, err := gokrazy.PrivateInterfaceAddrs()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
sshListeners.ListenAndServe(hosts, func(host string) multilisten.Listener {
|
||||||
|
return srv.listenerFor(host)
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func logic() error {
|
func logic() error {
|
||||||
prb := newPacketRingBuffer(50000)
|
prb := newPacketRingBuffer(50000)
|
||||||
|
srv, err := newServer(prb)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := updateListeners(srv); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
var eg errgroup.Group
|
go func() {
|
||||||
eg.Go(func() error { return listenAndServe(prb) })
|
ch := make(chan os.Signal, 1)
|
||||||
eg.Go(func() error {
|
signal.Notify(ch, syscall.SIGUSR1)
|
||||||
packets, err := capturePackets(context.Background())
|
for range ch {
|
||||||
if err != nil {
|
if err := updateListeners(srv); err != nil {
|
||||||
return err
|
log.Printf("updateListeners: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for packet := range packets {
|
}()
|
||||||
prb.writePacket(packet)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
|
|
||||||
return eg.Wait()
|
packets, err := capturePackets(context.Background())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for packet := range packets {
|
||||||
|
prb.writePacket(packet)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@ -7,7 +7,6 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
"github.com/gokrazy/gokrazy"
|
|
||||||
"github.com/google/gopacket/layers"
|
"github.com/google/gopacket/layers"
|
||||||
"github.com/google/gopacket/pcapgo"
|
"github.com/google/gopacket/pcapgo"
|
||||||
"golang.org/x/crypto/ssh"
|
"golang.org/x/crypto/ssh"
|
||||||
@ -104,7 +103,12 @@ func loadHostKey(path string) (ssh.Signer, error) {
|
|||||||
return ssh.ParsePrivateKey(b)
|
return ssh.ParsePrivateKey(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func listenAndServe(prb *packetRingBuffer) error {
|
type server struct {
|
||||||
|
config *ssh.ServerConfig
|
||||||
|
prb *packetRingBuffer
|
||||||
|
}
|
||||||
|
|
||||||
|
func newServer(prb *packetRingBuffer) (*server, error) {
|
||||||
config := &ssh.ServerConfig{
|
config := &ssh.ServerConfig{
|
||||||
PublicKeyCallback: func(conn ssh.ConnMetadata, pubKey ssh.PublicKey) (*ssh.Permissions, error) {
|
PublicKeyCallback: func(conn ssh.ConnMetadata, pubKey ssh.PublicKey) (*ssh.Permissions, error) {
|
||||||
return nil, nil // authorize all users
|
return nil, nil // authorize all users
|
||||||
@ -113,53 +117,56 @@ func listenAndServe(prb *packetRingBuffer) error {
|
|||||||
|
|
||||||
signer, err := loadHostKey(*hostKeyPath)
|
signer, err := loadHostKey(*hostKeyPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
config.AddHostKey(signer)
|
config.AddHostKey(signer)
|
||||||
|
|
||||||
accept := func(listener net.Listener) {
|
return &server{
|
||||||
for {
|
config: config,
|
||||||
conn, err := listener.Accept()
|
prb: prb,
|
||||||
if err != nil {
|
}, nil
|
||||||
log.Printf("accept: %v", err)
|
}
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
go func(conn net.Conn) {
|
func (s *server) listenerFor(host string) *serverListener {
|
||||||
_, chans, reqs, err := ssh.NewServerConn(conn, config)
|
return &serverListener{srv: s, host: host}
|
||||||
if err != nil {
|
}
|
||||||
log.Printf("handshake: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// discard all out of band requests
|
type serverListener struct {
|
||||||
go ssh.DiscardRequests(reqs)
|
srv *server
|
||||||
|
host string
|
||||||
|
ln net.Listener
|
||||||
|
}
|
||||||
|
|
||||||
for newChannel := range chans {
|
func (sl *serverListener) ListenAndServe() error {
|
||||||
handleChannel(newChannel, prb)
|
ln, err := net.Listen("tcp", net.JoinHostPort(sl.host, "5022"))
|
||||||
}
|
|
||||||
}(conn)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
addrs, err := gokrazy.PrivateInterfaceAddrs()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
sl.ln = ln
|
||||||
for _, addr := range addrs {
|
for {
|
||||||
hostport := net.JoinHostPort(addr, "5022")
|
conn, err := ln.Accept()
|
||||||
listener, err := net.Listen("tcp", hostport)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
fmt.Printf("listening on %s\n", hostport)
|
|
||||||
go accept(listener)
|
go func(conn net.Conn) {
|
||||||
|
_, chans, reqs, err := ssh.NewServerConn(conn, sl.srv.config)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("handshake: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// discard all out of band requests
|
||||||
|
go ssh.DiscardRequests(reqs)
|
||||||
|
|
||||||
|
for newChannel := range chans {
|
||||||
|
handleChannel(newChannel, sl.srv.prb)
|
||||||
|
}
|
||||||
|
}(conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("host key fingerprint: %s\n", ssh.FingerprintSHA256(signer.PublicKey()))
|
|
||||||
|
|
||||||
select {}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (sl *serverListener) Close() error {
|
||||||
|
return sl.ln.Close()
|
||||||
|
}
|
||||||
|
@ -600,10 +600,11 @@ func Apply(dir, root string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, process := range []string{
|
for _, process := range []string{
|
||||||
"dyndns", // depends on the public IPv4 address
|
"dyndns", // depends on the public IPv4 address
|
||||||
"dnsd", // listens on private IPv4/IPv6
|
"dnsd", // listens on private IPv4/IPv6
|
||||||
"diagd", // listens on private IPv4/IPv6
|
"diagd", // listens on private IPv4/IPv6
|
||||||
"backupd", // listens on private IPv4/IPv6
|
"backupd", // listens on private IPv4/IPv6
|
||||||
|
"captured", // listens on private IPv4/IPv6
|
||||||
} {
|
} {
|
||||||
if err := notify.Process("/user/"+process, syscall.SIGUSR1); err != nil {
|
if err := notify.Process("/user/"+process, syscall.SIGUSR1); err != nil {
|
||||||
log.Printf("notifying %s: %v", process, err)
|
log.Printf("notifying %s: %v", process, err)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user