Переход на локальный является самым быстрым и наиболее эффективным для вашего вопроса, поэтому (1).
Все это связано с тем, как ваш пакет маршрутизируется через вашу сеть.
Различие, которое я могу сразу заметить из вашего простого описания, заключается в использовании шлюза по сравнению с прямым подключением к ПК. Переходя на внешний адрес, вы будете использовать маршрутизатор (шлюз по умолчанию) и его ресурсы для установления соединения. Если этот маршрутизатор интенсивно используется, вы заметите значительное снижение пропускной способности вашего трафика.
Я бы сначала предложил проверить вашу таблицу маршрутизации в локальной системе
user@server:~$ route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.11.0.1 0.0.0.0 UG 0 0 0 eth0
10.11.0.0 0.0.0.0 255.255.252.0 U 0 0 0 eth0
Вы можете видеть из моей конфигурации, что, если я ссылаюсь на систему в локальной сети (т.е. 10.11.2.200), она будет идти непосредственно к этой системе. Если у меня есть для этого адрес NAT (т. Е. 10.11.2.200 NAT www.somedomain.net), он сначала отправится к маршрутизатору, а затем обратно в сеть.
Вы можете проверить это, запустив traceroute на внутренний IP-адрес, а затем сравнить его с IP-адресом NAT. (Желательно отключить разрешение имен в вашей трассировке).
user@server:~$ traceroute -n www.xxx.yyy.zzz
traceroute to www.xxx.yyy.zzz (www.xxx.yyy.zzz), 30 hops max, 60 byte packets
1 10.11.0.1 0.598 ms 0.717 ms 0.792 ms
2 10.10.1.3 0.710 ms 0.788 ms 0.896 ms
3 www.xxx.yyy.zzz 0.609 ms 0.496 ms 0.439 ms
Вы должны заметить, что заходите на шлюз по умолчанию (маршрутизатор), прежде чем вернуться обратно в сеть.
Сравните это с вашей прямой трассировкой
user@server:~$ traceroute -n 10.11.0.64
traceroute to 10.11.0.64 (10.11.0.64), 30 hops max, 60 byte packets
1 10.11.0.64 0.349 ms 0.343 ms 0.336 ms
Причина, по которой небольшая скорость передачи файлов была заметна, заключается в ее чрезвычайно малом размере, который занимал время для распределения ресурсов на маршрутизаторе. При передаче больших файлов время будет статистически незначимым, так как вы открываете соединение и оставляете его открытым. Тест, который даст вам другие результаты, будет посылать файл небольшого размера, но запускать его X раз, чтобы он равнялся размеру вашего файла в 100 МБ. Попробуйте, что с помощью скрипта, выполняющего команду 20 000 000 раз, вы получите 100 МБ.
cmd="ssh ... echo hello"; for ((i=0;i<10000000;i++)); do $cmd;done
(10 000 000 выполнений, потому что «echo_hello» имеет длину 10 байт, хотя результат больше, чем то, что было бы получено из простого пакета ACK для SCP). Этот сценарий - просто быстрое подтверждение концепции.
Я надеюсь, что это решит ваш вопрос правильно. Я хотел бы добавить, что это усложняется, если исходная и / или целевая системы имеют несколько интерфейсов в разных сетях.