Skip to content

Commit b182087

Browse files
committed
send rst to acme server to close tcp session
1 parent 476478b commit b182087

File tree

1 file changed

+34
-14
lines changed

1 file changed

+34
-14
lines changed

providers/http/nfqueue/nfqueue.go

+34-14
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ func craftkeyauthresponse(keyAuth string) []byte {
5050
}
5151

5252
// craft packet
53-
func craftReplyPacketBytes(keyAuth string, inputpacket gopacket.Packet) []byte {
53+
func craftReplyandSend(keyAuth string, inputpacket gopacket.Packet) error {
5454
outbuffer := gopacket.NewSerializeBuffer()
5555
opt := gopacket.SerializeOptions{
5656
FixLengths: true,
@@ -66,20 +66,36 @@ func craftReplyPacketBytes(keyAuth string, inputpacket gopacket.Packet) []byte {
6666
DstPort: inputTcp.SrcPort,
6767
Ack: inputTcp.Seq + uint32(len(inputTcp.Payload)),
6868
Seq: inputTcp.Ack,
69+
Window: 1,
6970
PSH: true,
7071
ACK: true,
7172
}
7273
// log.Infof("dstp: %s, srcp %s", tcplayer.DstPort.String(), tcp)
73-
//check network layer
74+
// check network layer
7475
// this is reply so we reverse sorce and dst ip
7576
iplayer := &layers.IPv4{
7677
SrcIP: inputIPv4.DstIP,
7778
DstIP: inputIPv4.SrcIP,
7879
}
7980
tcplayer.SetNetworkLayerForChecksum(iplayer)
8081
gopacket.SerializeLayers(outbuffer, opt, tcplayer, httplayer)
82+
// send http reply
83+
sendPacket(outbuffer.Bytes(), &iplayer.DstIP)
8184

82-
return outbuffer.Bytes()
85+
// craft RST packet to server so connection can close by webserver
86+
outbuffer.Clear()
87+
tcplayer.RST = true
88+
tcplayer.ACK = false
89+
tcplayer.PSH = false
90+
tcplayer.Seq = tcplayer.Seq + uint32(len(httplayer.Payload()))
91+
92+
tcplayer.SetNetworkLayerForChecksum(iplayer)
93+
gopacket.SerializeLayers(outbuffer, opt, tcplayer)
94+
// rst to acme server so it knows it's done,
95+
// our webserver will send some ack packet but it has misalign Seq so ignored by ACME server
96+
sendPacket(outbuffer.Bytes(), &iplayer.DstIP)
97+
98+
return nil
8399
}
84100

85101
// sendPacket sends packet: TODO: call cleanup if errors out
@@ -99,7 +115,7 @@ func sendPacket(packet []byte, DstIP *net.IP) error {
99115
// serve runs server by sniffing packets on firewall and inject response into it.
100116
// iptables ://
101117
func (w *HTTPProvider) serve(domain, token, keyAuth string) error {
102-
//run nfqueue start
118+
// run nfqueue start
103119
cmd := exec.Command("iptables", "-I", "INPUT", "-p", "tcp", "--dport", w.port, "-j", "NFQUEUE", "--queue-num", "8555")
104120
err := cmd.Run()
105121
// ensure even if clean funtion failed to called
@@ -120,17 +136,15 @@ func (w *HTTPProvider) serve(domain, token, keyAuth string) error {
120136
}
121137
defer nf.Close()
122138

123-
//handle Packet
139+
// handle Packet
124140
handlepacket := func(a gnfqueue.Attribute) int {
125141
id := *a.PacketID
126142
opt := gopacket.DecodeOptions{
127143
NoCopy: true,
128144
Lazy: false,
129145
}
130-
//assume ipv4 for now, will segfault
146+
// assume ipv4 for now, will segfault
131147
payload := gopacket.NewPacket(*a.Payload, layers.LayerTypeIPv4, opt)
132-
ipL := payload.Layer(layers.LayerTypeIPv4)
133-
srcip := ipL.(*layers.IPv4).SrcIP
134148
if tcpLayer := payload.Layer(layers.LayerTypeTCP); tcpLayer != nil {
135149
// Get actual TCP data from this layer
136150
inputTcp, _ := tcpLayer.(*layers.TCP)
@@ -142,12 +156,13 @@ func (w *HTTPProvider) serve(domain, token, keyAuth string) error {
142156
}
143157
// check token in http
144158
if strings.Contains(httpPayload.URL.Path, token) {
145-
//we got the token!, block the packet to backend server.
159+
// we got the token!, block the packet to backend server.
146160
nf.SetVerdict(id, gnfqueue.NfDrop)
147-
//forge our new reply
148-
replypacket := craftReplyPacketBytes(keyAuth, payload)
149-
// Send the modified packet back to VA, ignore err as it won't crash
150-
sendPacket(replypacket, &srcip)
161+
// forge our new reply
162+
err := craftReplyandSend(keyAuth, payload)
163+
if err != nil {
164+
return 0
165+
}
151166
// packet sent, end of function
152167
return 0
153168
} else {
@@ -162,8 +177,13 @@ func (w *HTTPProvider) serve(domain, token, keyAuth string) error {
162177
return 0
163178
}
164179

180+
ignoreerr := func(err error) int {
181+
log.Print(err)
182+
return 0
183+
}
184+
165185
// Register your function to listen on nflqueue queue
166-
err = nf.Register(w.context, handlepacket)
186+
err = nf.RegisterWithErrorFunc(w.context, handlepacket, ignoreerr)
167187
if err != nil {
168188
fmt.Println(err)
169189
return nil

0 commit comments

Comments
 (0)