@@ -50,7 +50,7 @@ func craftkeyauthresponse(keyAuth string) []byte {
50
50
}
51
51
52
52
// craft packet
53
- func craftReplyPacketBytes (keyAuth string , inputpacket gopacket.Packet ) [] byte {
53
+ func craftReplyandSend (keyAuth string , inputpacket gopacket.Packet ) error {
54
54
outbuffer := gopacket .NewSerializeBuffer ()
55
55
opt := gopacket.SerializeOptions {
56
56
FixLengths : true ,
@@ -66,20 +66,36 @@ func craftReplyPacketBytes(keyAuth string, inputpacket gopacket.Packet) []byte {
66
66
DstPort : inputTcp .SrcPort ,
67
67
Ack : inputTcp .Seq + uint32 (len (inputTcp .Payload )),
68
68
Seq : inputTcp .Ack ,
69
+ Window : 1 ,
69
70
PSH : true ,
70
71
ACK : true ,
71
72
}
72
73
// log.Infof("dstp: %s, srcp %s", tcplayer.DstPort.String(), tcp)
73
- //check network layer
74
+ // check network layer
74
75
// this is reply so we reverse sorce and dst ip
75
76
iplayer := & layers.IPv4 {
76
77
SrcIP : inputIPv4 .DstIP ,
77
78
DstIP : inputIPv4 .SrcIP ,
78
79
}
79
80
tcplayer .SetNetworkLayerForChecksum (iplayer )
80
81
gopacket .SerializeLayers (outbuffer , opt , tcplayer , httplayer )
82
+ // send http reply
83
+ sendPacket (outbuffer .Bytes (), & iplayer .DstIP )
81
84
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
83
99
}
84
100
85
101
// sendPacket sends packet: TODO: call cleanup if errors out
@@ -99,7 +115,7 @@ func sendPacket(packet []byte, DstIP *net.IP) error {
99
115
// serve runs server by sniffing packets on firewall and inject response into it.
100
116
// iptables ://
101
117
func (w * HTTPProvider ) serve (domain , token , keyAuth string ) error {
102
- //run nfqueue start
118
+ // run nfqueue start
103
119
cmd := exec .Command ("iptables" , "-I" , "INPUT" , "-p" , "tcp" , "--dport" , w .port , "-j" , "NFQUEUE" , "--queue-num" , "8555" )
104
120
err := cmd .Run ()
105
121
// ensure even if clean funtion failed to called
@@ -120,17 +136,15 @@ func (w *HTTPProvider) serve(domain, token, keyAuth string) error {
120
136
}
121
137
defer nf .Close ()
122
138
123
- //handle Packet
139
+ // handle Packet
124
140
handlepacket := func (a gnfqueue.Attribute ) int {
125
141
id := * a .PacketID
126
142
opt := gopacket.DecodeOptions {
127
143
NoCopy : true ,
128
144
Lazy : false ,
129
145
}
130
- //assume ipv4 for now, will segfault
146
+ // assume ipv4 for now, will segfault
131
147
payload := gopacket .NewPacket (* a .Payload , layers .LayerTypeIPv4 , opt )
132
- ipL := payload .Layer (layers .LayerTypeIPv4 )
133
- srcip := ipL .(* layers.IPv4 ).SrcIP
134
148
if tcpLayer := payload .Layer (layers .LayerTypeTCP ); tcpLayer != nil {
135
149
// Get actual TCP data from this layer
136
150
inputTcp , _ := tcpLayer .(* layers.TCP )
@@ -142,12 +156,13 @@ func (w *HTTPProvider) serve(domain, token, keyAuth string) error {
142
156
}
143
157
// check token in http
144
158
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.
146
160
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
+ }
151
166
// packet sent, end of function
152
167
return 0
153
168
} else {
@@ -162,8 +177,13 @@ func (w *HTTPProvider) serve(domain, token, keyAuth string) error {
162
177
return 0
163
178
}
164
179
180
+ ignoreerr := func (err error ) int {
181
+ log .Print (err )
182
+ return 0
183
+ }
184
+
165
185
// Register your function to listen on nflqueue queue
166
- err = nf .Register (w .context , handlepacket )
186
+ err = nf .RegisterWithErrorFunc (w .context , handlepacket , ignoreerr )
167
187
if err != nil {
168
188
fmt .Println (err )
169
189
return nil
0 commit comments