288 void block(
const std::wstring &openvpn_app_path,
289 NET_IFINDEX itf_index,
294 FWPM_FILTER0 filter = {};
295 FWPM_FILTER_CONDITION0 condition[2] = {};
296 FWPM_FILTER_CONDITION0 match_openvpn = {};
297 FWPM_FILTER_CONDITION0 match_port_53 = {};
298 FWPM_FILTER_CONDITION0 match_interface = {};
299 FWPM_FILTER_CONDITION0 match_loopback = {};
300 FWPM_FILTER_CONDITION0 match_not_loopback = {};
311 FWPM_SUBLAYER0 subLayer = {};
313 subLayer.displayData.name =
const_cast<wchar_t *
>(L
"OpenVPN");
314 subLayer.displayData.description =
const_cast<wchar_t *
>(L
"OpenVPN");
316 subLayer.weight = 0x100;
319 const DWORD status = ::FwpmSubLayerAdd0(
engineHandle(), &subLayer, NULL);
320 if (status != ERROR_SUCCESS)
321 OPENVPN_THROW(wfp_error,
"FwpmSubLayerAdd0 failed with status=0x" << std::hex << status);
325 match_openvpn.fieldKey = FWPM_CONDITION_ALE_APP_ID;
326 match_openvpn.matchType = FWP_MATCH_EQUAL;
327 match_openvpn.conditionValue.type = FWP_BYTE_BLOB_TYPE;
328 match_openvpn.conditionValue.byteBlob = openvpn_app_id_blob.get();
330 match_port_53.fieldKey = FWPM_CONDITION_IP_REMOTE_PORT;
331 match_port_53.matchType = FWP_MATCH_EQUAL;
332 match_port_53.conditionValue.type = FWP_UINT16;
333 match_port_53.conditionValue.uint16 = 53;
335 match_interface.fieldKey = FWPM_CONDITION_IP_LOCAL_INTERFACE;
336 match_interface.matchType = FWP_MATCH_EQUAL;
337 match_interface.conditionValue.type = FWP_UINT64;
338 match_interface.conditionValue.uint64 = &itf_luid.Value;
340 match_loopback.fieldKey = FWPM_CONDITION_FLAGS;
341 match_loopback.matchType = FWP_MATCH_FLAGS_ALL_SET;
342 match_loopback.conditionValue.type = FWP_UINT32;
343 match_loopback.conditionValue.uint32 = FWP_CONDITION_FLAG_IS_LOOPBACK;
345 match_not_loopback.fieldKey = FWPM_CONDITION_FLAGS;
346 match_not_loopback.matchType = FWP_MATCH_FLAGS_NONE_SET;
347 match_not_loopback.conditionValue.type = FWP_UINT32;
348 match_not_loopback.conditionValue.uint32 = FWP_CONDITION_FLAG_IS_LOOPBACK;
352 filter.displayData.name =
const_cast<wchar_t *
>(L
"OpenVPN");
353 filter.weight.type = FWP_UINT8;
354 filter.weight.uint8 = 0xF;
355 filter.filterCondition = condition;
358 filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V4;
359 filter.action.type = FWP_ACTION_PERMIT;
360 filter.numFilterConditions = 1;
361 condition[0] = match_openvpn;
363 log <<
"permit IPv4 requests from OpenVPN app" << std::endl;
367 filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V6;
369 log <<
"permit IPv6 requests from OpenVPN app" << std::endl;
373 filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V4;
374 filter.action.type = FWP_ACTION_BLOCK;
375 filter.weight.type = FWP_EMPTY;
376 filter.numFilterConditions = 1;
377 condition[0] = match_not_loopback;
381 filter.numFilterConditions = 2;
382 condition[1] = match_port_53;
386 log <<
"block IPv4 " << dns_str <<
"requests from other apps" << std::endl;
390 filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V6;
392 log <<
"block IPv6 " << dns_str <<
"requests from other apps" << std::endl;
396 filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V4;
397 filter.action.type = FWP_ACTION_PERMIT;
398 filter.numFilterConditions = 1;
399 condition[0] = match_interface;
401 log <<
"allow IPv4 traffic from TAP" << std::endl;
405 filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V6;
407 log <<
"allow IPv6 traffic from TAP" << std::endl;
412 filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V4;
413 filter.action.type = FWP_ACTION_BLOCK;
414 filter.weight.type = FWP_EMPTY;
415 filter.numFilterConditions = 2;
416 condition[0] = match_loopback;
417 condition[1] = match_port_53;
419 log <<
"block IPv4 DNS requests to loopback from other apps" << std::endl;
423 filter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V6;
425 log <<
"block IPv6 DNS requests to loopback from other apps" << std::endl;