captured: use multilisten

This commit is contained in:
Michael Stapelberg 2018-06-27 19:44:39 +02:00
parent c24eefbb51
commit 2b3cf0bf61
3 changed files with 92 additions and 55 deletions

View File

@ -7,14 +7,18 @@ import (
"context"
"flag"
"log"
"os"
"os/signal"
"sync"
"syscall"
"router7/internal/multilisten"
"github.com/gokrazy/gokrazy"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcapgo"
"golang.org/x/sync/errgroup"
_ "net/http/pprof"
)
@ -79,12 +83,40 @@ func (prb *packetRingBuffer) packetsLocked() []gopacket.Packet {
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 {
prb := newPacketRingBuffer(50000)
srv, err := newServer(prb)
if err != nil {
return err
}
if err := updateListeners(srv); err != nil {
return err
}
go func() {
ch := make(chan os.Signal, 1)
signal.Notify(ch, syscall.SIGUSR1)
for range ch {
if err := updateListeners(srv); err != nil {
log.Printf("updateListeners: %v", err)
}
}
}()
var eg errgroup.Group
eg.Go(func() error { return listenAndServe(prb) })
eg.Go(func() error {
packets, err := capturePackets(context.Background())
if err != nil {
return err
@ -93,9 +125,6 @@ func logic() error {
prb.writePacket(packet)
}
return nil
})
return eg.Wait()
}
func main() {

View File

@ -7,7 +7,6 @@ import (
"log"
"net"
"github.com/gokrazy/gokrazy"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcapgo"
"golang.org/x/crypto/ssh"
@ -104,7 +103,12 @@ func loadHostKey(path string) (ssh.Signer, error) {
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{
PublicKeyCallback: func(conn ssh.ConnMetadata, pubKey ssh.PublicKey) (*ssh.Permissions, error) {
return nil, nil // authorize all users
@ -113,20 +117,40 @@ func listenAndServe(prb *packetRingBuffer) error {
signer, err := loadHostKey(*hostKeyPath)
if err != nil {
return err
return nil, err
}
config.AddHostKey(signer)
accept := func(listener net.Listener) {
for {
conn, err := listener.Accept()
return &server{
config: config,
prb: prb,
}, nil
}
func (s *server) listenerFor(host string) *serverListener {
return &serverListener{srv: s, host: host}
}
type serverListener struct {
srv *server
host string
ln net.Listener
}
func (sl *serverListener) ListenAndServe() error {
ln, err := net.Listen("tcp", net.JoinHostPort(sl.host, "5022"))
if err != nil {
log.Printf("accept: %v", err)
continue
return err
}
sl.ln = ln
for {
conn, err := ln.Accept()
if err != nil {
return err
}
go func(conn net.Conn) {
_, chans, reqs, err := ssh.NewServerConn(conn, config)
_, chans, reqs, err := ssh.NewServerConn(conn, sl.srv.config)
if err != nil {
log.Printf("handshake: %v", err)
return
@ -136,30 +160,13 @@ func listenAndServe(prb *packetRingBuffer) error {
go ssh.DiscardRequests(reqs)
for newChannel := range chans {
handleChannel(newChannel, prb)
handleChannel(newChannel, sl.srv.prb)
}
}(conn)
}
}
addrs, err := gokrazy.PrivateInterfaceAddrs()
if err != nil {
return err
}
for _, addr := range addrs {
hostport := net.JoinHostPort(addr, "5022")
listener, err := net.Listen("tcp", hostport)
if err != nil {
return err
}
fmt.Printf("listening on %s\n", hostport)
go accept(listener)
}
fmt.Printf("host key fingerprint: %s\n", ssh.FingerprintSHA256(signer.PublicKey()))
select {}
return nil
}
func (sl *serverListener) Close() error {
return sl.ln.Close()
}

View File

@ -604,6 +604,7 @@ func Apply(dir, root string) error {
"dnsd", // listens on private IPv4/IPv6
"diagd", // 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 {
log.Printf("notifying %s: %v", process, err)