формирование трафика на OSX 10.10 с pfctl и dnctl

Я пытаюсь сделать формирование трафика (регулировка) на Mac OS X 10.10 через pfctl и dnctl.

Я реализовал простой тестовый сервер и клиент с netcat (nc) и синтетический случайный файл полезной нагрузки, чтобы проверить, работает ли моя регулировка канала dummynet правильно. До сих пор пытаясь настроить канал dummynet с помощью murus брандмауэра приложение для GUI, кажется, правильно не регулирует трафик (передача 64 МБ завершается в ~200ms).

Вот сценарий оболочки удара OSX (требует brew install coreutils для gdate) это - полный пример. Если Вы выполняете его в одном терминале как:

./throttle-test.sh server

и другой как

./throttle-test.sh client

Они попытаются передать полезную нагрузку 64 МБ по Вашему en0 интерфейс (не использование lo0 потому что его огромный MTU не походит на трафик WAN).

Я также протестировал передачу файла к удаленному ноутбуку Linux, чтобы видеть, обходили ли источник и целевой IP оба являющийся локальным дюйм/с регулировку, но даже к удаленной машине на моей LAN/Wi-Fi скорость намного быстрее, чем отрегулированный предел.

Мой вопрос - то, что было бы корректным сценарием для конфигурирования pfctl и dnctl отрегулировать эту передачу файлов к данному пределу пропускной способности (говорят что 8 Мбит/с, например). Объемом регулировки может быть определенный порт TCP.

Обратите внимание, что OS X 10.10 больше не включает ipfw таким образом, я ищу что-то использование pfctl и dnctl.

Вот мой throttle-test.sh файл:

#!/bin/bash
set -o errexit    # always exit on error
set -o errtrace   # trap errors in functions as well
set -o pipefail   # don't ignore exit codes when piping output
set -o posix      # more strict failures in subshells
# set -x          # enable debugging

IFS="$(printf "\n\t")"

setup_payload() {
  local payload_path="$1"
  local size_kbytes="$2"
  mkdir -p $(basename "${payload_path}")

  if [[ -f "${payload_path}" ]]; then
    local on_disk=$(wc -c < "${payload_path}")
  fi
  if [[ ${on_disk} -ne $((${size_kbytes} * 1024)) ]]; then
    echo "creating payload file ${payload_path}"
    dd if=/dev/urandom of="${payload_path}" \
      bs=1024 count="${size_kbytes}" &> /dev/null
  fi
}

start_server() {
  local payload_path="$1"
  local ip="$2"
  local port="$3"
  while true; do
    echo "Starting netcat server for ${payload_path} on ${ip}:${port}"
    nc -l "${ip}" "${port}" < "${payload_path}"
    sleep 1
  done
}

hash() {
  shasum -a 256 "$1" | cut -d " " -f 1
}

verify_hashes() {
  # Sanity check no funny business
  from_hash=$(hash "$1")
  to_hash=$(hash "$2")
  if [[ "${from_hash}" != "${to_hash}" ]]; then
    echo "checksums did not match ${from_hash} ${to_hash}" 1>&2
    exit 10
  fi
}

client() {
  local payload_path="$1"
  local ip="$2"
  local port="$3"

  # time how long it takes to transfer the payload file
  start=$(gdate +%s%3N)
  nc -d "${ip}" "${port}" > "${payload_path}.client"
  stop=$(gdate +%s%3N)

  verify_hashes "${payload_path}" "${payload_path}.client"

  local duration=$((${stop} - ${start}))
  echo "${duration}"
}

main() {
  local size_kbytes=$((64 * 1024)) # 64 MB
  local payload_path="/tmp/throttle-test/data-${size_kbytes}.bin"
  local port="${PORT-9112}"
  # You may need to change this if you are on linux
  local interface="${INTERFACE-en0}"
  local ip=$(ipconfig getifaddr "${interface}")

  setup_payload "${payload_path}" "${size_kbytes}"
  case "$1" in
    server)
      start_server "${payload_path}" "${ip}" "${port}"
    ;;
    client)
      local duration=$(client "${payload_path}" "${ip}" "${port}")
      echo "Transfered ${size_kbytes} kbytes in ${duration} ms"
    ;;
    *)
      echo "Usage: $0 <server|client>"
    ;;
  esac
}

main "$@"

Обновление

Вот то, что я имею до сих пор. Это, кажется, работает правильно на направление загрузки, но не дроссель вообще в направлении загрузки.

throttle_start() {
  local down_mbps="$1"
  local up_mbps="$2"
  local delay=$(($3 / 2))
  sudo dnctl pipe 1 config bw "${down_mbps}Mbit/s" delay "${delay}"
  sudo dnctl pipe 2 config bw "${up_mbps}Mbit/s" delay "${delay}"
  (cat /etc/pf.conf && \
    echo 'dummynet-anchor "throttle"' && \
    echo 'anchor "throttle"') | sudo pfctl -f -
  cat << EOF | sudo pfctl -a throttle -f -
dummynet in quick proto tcp from any port = 9112 to any pipe 1
dummynet out quick proto tcp from any to any port = 9112 pipe 2
EOF
  sudo pfctl -q -e
}
1
задан 28 September 2015 в 23:15
1 ответ

Это сценарий, который я с некоторым успехом использовал в El Capitan 10.11:

#!/bin/bash

# Reset dummynet to default config
dnctl -f flush

# Compose an addendum to the default config: creates a new anchor
(cat /etc/pf.conf &&
  echo 'dummynet-anchor "my_anchor"' &&
  echo 'anchor "my_anchor"') | pfctl -q -f -

# Configure the new anchor
cat <<EOF | pfctl -q -a my_anchor -f -
no dummynet quick on lo0 all
dummynet out proto tcp from any to any port 1:65535 pipe 1
EOF

# Create the dummynet queue
dnctl pipe 1 config bw 40000byte/s

# Activate PF
pfctl -E

# to check that dnctl is properly configured: sudo dnctl list

Единственное существенное отличие похоже на no dummynet quick on lo0 all , который я не Не знаю, что он делает, нашел здесь: https://www.reddit.com/r/osx/comments/3g7dim/limiting_bandwidth_per_application/

2
ответ дан 3 December 2019 в 20:47

Теги

Похожие вопросы