@@ -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 ://
101117func (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