매우 낮은 TCP OpenVPN 처리량 (100Mbit 포트, 낮은 CPU 사용률)


27

두 서버 간의 OpenVPN 전송 속도가 매우 느립니다. 이 질문에서는 서버 A와 서버 B를 호출하겠습니다.

서버 A와 서버 B 모두 CentOS 6.6을 실행하고 있습니다. 둘 다 100Mbit 회선이있는 데이터 센터에 있으며 OpenVPN 외부의 두 서버 간의 데이터 전송은 ~ 88Mbps에 가깝습니다.

그러나 서버 A와 서버 B간에 설정 한 OpenVPN 연결을 통해 파일을 전송하려고하면 6.5Mbps 정도의 처리량을 얻습니다.

iperf의 테스트 결과 :

[  4] local 10.0.0.1 port 5001 connected with 10.0.0.2 port 49184
[  4]  0.0-10.0 sec  7.38 MBytes  6.19 Mbits/sec
[  4]  0.0-10.5 sec  7.75 MBytes  6.21 Mbits/sec
[  5] local 10.0.0.1 port 5001 connected with 10.0.0.2 port 49185
[  5]  0.0-10.0 sec  7.40 MBytes  6.21 Mbits/sec
[  5]  0.0-10.4 sec  7.75 MBytes  6.26 Mbits/sec

이러한 OpenVPN iperf 테스트 외에도 두 서버 모두로드가 0 인 상태에서 거의 완전히 유휴 상태입니다.

서버 A에는 IP 10.0.0.1이 할당되며 OpenVPN 서버입니다. 서버 B에는 IP 10.0.0.2가 할당되며 OpenVPN 클라이언트입니다.

서버 A의 OpenVPN 구성은 다음과 같습니다.

port 1194
proto tcp-server
dev tun0
ifconfig 10.0.0.1 10.0.0.2
secret static.key
comp-lzo
verb 3

서버 B의 OpenVPN 구성은 다음과 같습니다.

port 1194
proto tcp-client
dev tun0
remote 204.11.60.69
ifconfig 10.0.0.2 10.0.0.1
secret static.key
comp-lzo
verb 3

내가 주목 한 것 :

1. 첫 번째 생각은 서버의 CPU 병목 현상이 발생한 것입니다. OpenVPN은 단일 스레드이며 두 서버 모두 가장 빠른 인텔 제온 L5520 프로세서를 실행합니다. 그러나 topiperf 테스트 중 하나 에서 명령을 실행하고 1코어 별 CPU 사용률을 보려고 누르면 각 코어에서 CPU 부하가 매우 낮다는 것을 알았습니다.

top - 14:32:51 up 13:56,  2 users,  load average: 0.22, 0.08, 0.06
Tasks: 257 total,   1 running, 256 sleeping,   0 stopped,   0 zombie
Cpu0  :  2.4%us,  1.4%sy,  0.0%ni, 94.8%id,  0.3%wa,  0.0%hi,  1.0%si,  0.0%st
Cpu1  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu2  :  0.0%us,  0.0%sy,  0.0%ni, 99.7%id,  0.0%wa,  0.0%hi,  0.0%si,  0.3%st
Cpu3  :  0.3%us,  0.0%sy,  0.0%ni, 99.7%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu4  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu5  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu6  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu7  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu8  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu9  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu10 :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu11 :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu12 :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu13 :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu14 :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu15 :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:    946768k total,   633640k used,   313128k free,    68168k buffers
Swap:  4192188k total,        0k used,  4192188k free,   361572k cached

2. iperf를 실행하는 동안 핑 시간은 OpenVPN을 터널을 통해 상당히 증가한다. iperf가 실행 중이 아닌 경우 터널에서 핑 시간은 일관되게 60ms입니다 (정상). 그러나 iperf가 실행 중이고 많은 트래픽을 발생 시키면 핑 시간이 불규칙 해집니다. iperf 테스트를 시작했을 때 네 번째 핑까지 핑 시간이 어떻게 안정적인지 아래에서 확인할 수 있습니다.

PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=60.1 ms
64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=60.1 ms
64 bytes from 10.0.0.2: icmp_seq=3 ttl=64 time=60.2 ms
** iperf test begins **
64 bytes from 10.0.0.2: icmp_seq=4 ttl=64 time=146 ms
64 bytes from 10.0.0.2: icmp_seq=5 ttl=64 time=114 ms
64 bytes from 10.0.0.2: icmp_seq=6 ttl=64 time=85.6 ms
64 bytes from 10.0.0.2: icmp_seq=7 ttl=64 time=176 ms
64 bytes from 10.0.0.2: icmp_seq=8 ttl=64 time=204 ms
64 bytes from 10.0.0.2: icmp_seq=9 ttl=64 time=231 ms
64 bytes from 10.0.0.2: icmp_seq=10 ttl=64 time=197 ms
64 bytes from 10.0.0.2: icmp_seq=11 ttl=64 time=233 ms
64 bytes from 10.0.0.2: icmp_seq=12 ttl=64 time=152 ms
64 bytes from 10.0.0.2: icmp_seq=13 ttl=64 time=216 ms

3. 위에서 언급했듯이 OpenVPN 터널 외부에서 iperf를 실행했으며 처리량은 ~ 88Mbps로 일정했습니다.

내가 시도한 것 :

1. 압축이 문제가 될 수 있다고 생각했기 때문에 comp-lzo두 구성에서 모두 제거 하고 OpenVPN을 다시 시작 하여 압축을 해제했습니다 . 개선이 없습니다.

2. 이전에 CPU 사용률이 낮다는 것을 알았지 만 기본 암호는 시스템이 유지하기에는 너무 집중적이라고 생각했습니다. 그래서 cipher RC2-40-CBC두 구성 (매우 가벼운 암호)에 추가하고 OpenVPN을 다시 시작했습니다. 개선이 없습니다.

3. 조각, mssfix 및 mtu-tun을 조정하여 성능을 향상시키는 방법에 대한 다양한 포럼을 읽었습니다. 이 기사 에서 설명한 것처럼 몇 가지 변형을 연주 했지만 다시는 개선되지 않았습니다.

OpenVPN 성능 저하의 원인에 대한 아이디어가 있습니까?


여기에 링크, 의견이 도움이 되나요? forums.openvpn.net/topic10593.html
Matt

내가 이미 시도한 것들의 대부분은 다음과 같습니다. 1. CPU 병목 현상을 확인하고, 2. VPN없이 전송 속도를 확인하고, 3. 압축을 토글하고, 4. 더 빠른 암호를 선택하십시오. 아직 :-/ 기괴합니다. 느린 속도와 높은 / 휘발성 핑 시간 외에도 병목 현상이 발생하는 위치에 대한 다른 표시는 없습니다.
Elliot B.

두 머신이 동일한 데이터 센터에 있습니까? 동일한 데이터 센터 내에서 60ms는 매우 높습니다. 나는 cipher none그것이 도움이 될지 의심하지만 시도 하고 싶은 유혹을받을 수 있습니다 .
Zoredache

@Zoredache 죄송합니다. 서버 위치에 대해 잘 모르겠습니다. 서버 A는 Dallas에 있고 서버 B는 Seattle에 있습니다.
Elliot B.

MTU를 확인 했습니까? Esp : tun-mtu, fragment 및 mssfix 매개 변수? 문서
Lenniey

답변:


26

많은 인터넷 검색 및 구성 파일 조정 후 솔루션을 찾았습니다. 나는 현재 60Mbps의 속도를 유지하고 최대 80Mbps까지 버스트하고있다. VPN 외부에서 수신하는 전송 속도보다 약간 느리지 만 이것이 가능한 한 좋은 것으로 생각합니다.

첫 번째 단계는 집합이었다 sndbuf 0rcvbuf 0서버와 클라이언트 모두에 OpenVPN을 구성한다.

나는 여기에 인용 할 공개 포럼 게시물 ( 러시아 원문 의 영어 번역) 에서 제안을보고 나서 그 변경을 했습니다.

2004 년 7 월입니다. 선진국의 일반적인 홈 인터넷 속도는 256-1024Kbit / s이며, 선진국의 경우 인터넷 속도는 56Kbit / s입니다. Linux 2.6.7은 오래 전에 출시되지 않았으며 TCP Windows 크기 조정이 기본적으로 활성화되는 2.6.8은 한 달만에 릴리스됩니다. OpenVPN은 이미 3 년 동안 개발 중이며 2.0 버전이 거의 릴리스되었습니다. 개발자 중 한 명이 소켓 버퍼 용 코드를 추가하기로 결정했습니다 .OS 사이의 버퍼 크기를 통합한다고 생각합니다. Windows에서 사용자 정의 버퍼 크기가 설정되면 어댑터의 MTU에 문제가 발생하여 마지막으로 다음 코드로 변환됩니다.

#ifndef WIN32
o->rcvbuf = 65536;
o->sndbuf = 65536;
#endif

OpenVPN을 사용한 경우 TCP 및 UDP를 통해 작동 할 수 있음을 알아야합니다. 사용자 지정 TCP 소켓 버퍼 값을 64KB로 낮게 설정하면 TCP 창 크기 조정 알고리즘이 창 크기를 64KB 이상으로 조정할 수 없습니다. 그게 무슨 뜻이야? 이는 긴 팻 링크를 통해 다른 VPN 사이트에 연결하는 경우 (예 : 약 100ms의 ping으로 미국에서 러시아로) 기본 OpenVPN 버퍼 설정으로 5.12Mbit / s 이상의 속도를 얻을 수 없음을 의미합니다. 해당 링크를 통해 50Mbit / s를 얻으려면 640KB 이상의 버퍼가 필요합니다. UDP는 창 크기가 없지만 매우 빠르게 작동하지 않기 때문에 더 빨리 작동합니다.

이미 짐작 하겠지만 최신 OpenVPN 릴리스는 여전히 64KB 소켓 버퍼 크기를 사용합니다. 이 문제를 어떻게 해결해야합니까? 가장 좋은 방법은 OpenVPN이 사용자 정의 버퍼 크기를 설정하지 못하게하는 것입니다. 서버 및 클라이언트 구성 파일 모두에 다음 코드를 추가해야합니다.

sndbuf 0
rcvbuf 0

클라이언트 구성을 직접 제어 할 수없는 경우 버퍼 크기 조정을 클라이언트에 푸시하는 방법을 설명합니다.

이러한 변경을 수행 한 후 처리 속도는 최대 20Mbps까지 상승했습니다. 그런 다음 단일 코어에서 CPU 사용률이 약간 높았으므로 comp-lzo클라이언트와 서버의 구성에서 (압축)을 제거했습니다 . 유레카! 전송 속도가 60Mbps 지속 및 80Mbps 버스트까지 증가했습니다.

이것이 누군가 OpenVPN 속도 저하 문제를 해결하는 데 도움이되기를 바랍니다.


4

일부 시도 후, 나는 좋은 해결책에 도달했습니다. 제 경우에는 @Elliot의 답변이 도움이되지 않았습니다. 인터넷 검색을 통해이 스 니펫을 발견하여 서버 구성을 추가하여 작업을 수행했습니다.

sndbuf 393216
rcvbuf 393216
push "sndbuf 393216"
push "rcvbuf 393216"

Raspberry PI3 에서 실행중인 작은 OpenVPN 서버가 있으며 이제 71Mbps 다운 링크 및 16Mbps 업 링크를 얻습니다 . CPU의 전원으로 인해 다운로드가 제한됩니다. 현재 내 구성은 다음과 같습니다.

client-to-client
duplicate-cn
keepalive 10 120
cipher AES-128-CBC
#cipher AES-256-CBC <<<---- lowers the speed to around 50Mbps, still not bad
comp-lzo
user nobody
group nogroup
persist-key
persist-tun
tun-mtu 9000

OpenSSL 1.0.2l을 사용하는 OpenVPN 2.4.0 arm-unknown-linux-gnueabihf

버퍼의 기본 구성에 대한 이러한 문제가 여전히 존재하는 것은 너무 이상합니다.

[편집] 내 client.ovpn 파일은 다음과 같이 구성되어 있습니다 :

client
dev tun
proto tcp
remote SERVER.IP.ADDRESS.HERE
resolv-retry infinite
nobind
persist-key
persist-tun
mute-replay-warnings
ns-cert-type server
tun-mtu 9000
key-direction 1
cipher AES-128-CBC
comp-lzo
verb 1
mute 20
<ca>
-----BEGIN CERTIFICATE-----
[...]
-----END CERTIFICATE-----
</ca>
<cert>
-----BEGIN CERTIFICATE-----
[...]
-----END CERTIFICATE-----
</cert>
<key>
-----BEGIN RSA PRIVATE KEY-----
[...]
-----END RSA PRIVATE KEY-----
</key>
<tls-auth>
-----BEGIN OpenVPN Static key V1-----
[...]
-----END OpenVPN Static key V1-----
</tls-auth>

버퍼 크기를 설정하면 도움이되었습니다.
Rolf

클라이언트 .ovpn 파일에 무엇을 넣었습니까?
Patoshi パ ト シ

@Patoshi パ ト シ sndbuf와 recbuf를 주석 처리하고 해당 암호와 압축을 넣고 기본 매개 변수를 그대로 두었습니다.
커널

@Kernel 당신은 당신이 당신의 클라이언트에 무엇을 보여줄 수 있습니까? 홍콩에서 뉴욕으로 OpenVPN 연결을하고 있으며 임의로 느리고 때로는 연결이 끊어집니다. 왜 그런지 잘 모르겠습니다.
Patoshi パ ト シ

@Patoshi パ ト シ 답글을 수정했습니다. 다시 확인하십시오. 그럼에도 불구하고 서버와의 불안정한 링크 문제를 해결하는 데 도움이 될 수 있기 때문에 대신 UDP를 사용하는 것이 좋습니다. 실제로, 그것은 단지 가정에 불과합니다.이 상황 에서이 솔루션을 벤치마킹하려고 시도한 적이 없습니다.
커널

1

구성에 따르면 터널의 전송으로 TCP를 사용하고 있습니다. 스택 TCP 연결 텐트가 패킷 손실 상황에서 문제를 발생시키기 때문에 TCP 대신 UDP를 사용하는 것이 좋습니다.

참조로 TCP over TCP가 나쁜 생각 인 이유를 참조하십시오.


불행히도 UDP는 우리에게 옵션이 아닙니다. 전송하는 데이터 패킷이 예상대로 도착하는지 확인해야합니다. 그럼에도 불구하고 우리는 이전에 UDP를 실험했지만 전송 속도가 여전히 문제였습니다.
Elliot B.

6
We need to ensure that the data packets we transmit arrive as expected.터널링되는 프로토콜에 의해 처리되지 않습니까? 왜 터널이 그것을 강제하는 것이라고 생각하십니까?
Zoredache

그럴 수도 있지만, 장거리 비동기 DRBD 구현 (예 : 파일 시스템 복제)에 OpenVPN을 사용하고 있습니다. 데이터 무결성은 정말로 중요하므로 DRBD에는 전송 무결성을 확인하기위한 내부 메커니즘이있을 수 있지만 TCP에 유지하는 것이 좋습니다. 어느 쪽이든, UDP에서 사용할 때 여전히 처리량이 낮습니다.
Elliot B.

3
@ElliotB. DRBD 자체는 복제에 TCP를 사용하므로 OpenVPN UDP 패킷이 손실 된 경우 재전송됩니다. 실제로이 경우 TCP를 사용하면 하나 대신 두 가지 재전송을 수행합니다. 하나는 버려 질 것입니다. 그리고 DRBD 트래픽이없는 꽤 긴 창을 만들 수도 있습니다 (이로 인해 복제가 중단 될 수도 있음). 경로에 패킷 손실이 생기면 이것이 얼마나 나쁜 생각인지 알 수 있습니다.
Fox

@Fox 설명을 해주셔서 감사합니다! 실제로 DRBD는 TCP (drbd.linbit.com/users-guide/s-prepare-network.html)를 사용합니다. Lairsdragon은 UDP 로의 전송 속도가 매우 느리기 때문에 UDP로 전환하라는 제안은 당시에는 관련이 없었지만 위에서 게시 한 솔루션을 구현 한 후에 UDP로 전환하여 몇 Mbps의 또 다른 성능 향상을 경험했습니다.
Elliot B.

1

서로 연결되는 두 개의 대륙간 서버가 있으며 그 사이의 속도는 약 220 Mbit / s입니다.

그러나 (UDP) OpenVPN 터널 내에서 속도는 평균 21Mbit / s로 약 10 배 느립니다.

(서버간에 상당한 대기 시간이 있습니다. 약 130ms이며 전송은 TCP 모드에서 Iperf3를 사용하여 측정되었습니다.)

이 글을 쓰는 시점에서 여기에 대한 답변에 대한 모든 제안을 시도했지만 아무런 도움이되지 않았습니다.

마침내 도움이 된 한 가지는 다음과 같습니다.

--txqueuelen 4000

OpenVPN 참조 매뉴얼에 따르면 :

–txqueuelen n 
(Linux only) Set the TX queue length on the TUN/TAP interface. Currently defaults to 100.

서버와 클라이언트에서이 매개 변수를 설정 한 후 OpenVPN 터널에서도 동일한 '직접 링크'속도 (~ 250Mbit / s)에 도달 할 수있었습니다.

나는 이미 rcvbuf 0and을 사용하고 sndbuf 0있었지만 적어도 혼자서 는 전혀 도움이되지 않았습니다.

: 나는 모두 이러한 권장 사항을 발견했습니다 OpenVPN을 포럼에이 페이지를 도에, UDPspeeder 위키에서이 페이지 .

또 다른 참고 사항 : iperf에서 UDP 전송을 사용하여 더 높은 속도에 도달 할 수 있었지만 그렇게하면 패킷 손실이 상당히 높아질 수 있습니다.

우연히 링크를 사용하여 두 곳을 터널링하기 위해 VPN을 사용해야하는 경우 VPN 자체에서 일종의 FEC (Forward-Error-Corctionction) 터널을 사용하는 것이 좋습니다. 내가 찾은 두 가지 작업은 다음과 같습니다.

  • 위에서 언급 한 UDPspeeder 는 UDP 연결을 터널링합니다.
  • TCP 연결을 터널링하는 kcptun ;

둘 다 패킷 손실로 많은 도움을 줄 수 있으며 (처음에 더 많은 대역폭을 소비 함) 궁극적으로 추가 오버 헤드가 있어도 높은 데이터 처리량으로 이어질 수 있습니다.

( 패킷 손실은 네트워크 , 특히 TCP를 망칠 수 있기 때문 입니다. 6 페이지를 참조하십시오.)

모든 일반적인 이유로 UDP에서 OpenVPN을 사용하는 것을 선호했지만 100ms 이상의 대기 시간과> 10 Mbit / s 속도를 모두 사용하는 경우 UDPspeeder를 다루기가 어렵다는 것을 알았습니다.

kcptun 그러나, 실제로는 아주 작은 미세 조정과 함께 좋은 일을하고, 정말 서로 처리량 우리 서버 증가했다. =)

확장 된 메모에서, 여기 당신의 OpenVPN 성능의 일부를 조정에 대한 좀 더 자세한 설명을 찾을 수 있습니다.


0

저에게 일본에는 openvpn 서버가 설치된 VPS 서버가 있었고 클라이언트 연결은 NYC의 OpenVPN 클라이언트 모드에서 DDWRT를 사용하고있었습니다. 100mbit 연결에서 1-2mbps 만 얻었습니다. 내가 그것을 최적화 할 수 있었던 최고는 5mbps 였고, 내가 필요로하는 것으로 충분하다고 생각했습니다.

내 OpenVPN 서버 설정 :

tun-mtu 9000
sndbuf 393216
rcvbuf 393216
push "sndbuf 393216"
push "rcvbuf 393216"
comp-lzo
txqueuelen 4000
######
port 10111
proto udp
dev tun
user nobody
group nobody
persist-key
persist-tun
keepalive 10 120
topology subnet
server x.x.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "dhcp-option DNS 1.0.0.1"
push "dhcp-option DNS 1.1.1.1"
push "redirect-gateway def1 bypass-dhcp"
dh none
ecdh-curve prime256v1
#tls-crypt tls-crypt.key 0
crl-verify crl.pem
ca ca.crt
cert server_IzA1QdFzHLRFfEoQ.crt
key server_IzA1QdFzHLRFfEoQ.key
auth SHA256
#cipher AES-128-GCM
#cipher AES-128-CBC
#ncp-ciphers AES-128-GCM
#ncp-ciphers AES-128-CBC
#tls-server
#tls-version-min 1.2
#tls-cipher TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256
#tls-cipher TLS-DHE-RSA-WITH-AES-128-CBC-SHA
status /var/log/openvpn/status.log
verb 3

내 DDWRT OpenVPN 클라이언트 설정도 스크린 샷에서 볼 수 있습니다.

tun-mtu 9000
comp-lzo
##########
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
verify-x509-name server_IzA1QdFzHLRFfEoQ name
auth SHA256
auth-nocache
setenv opt block-outside-dns # Prevent Windows 10 DNS leak
verb 3

여기에 이미지 설명을 입력하십시오

여기에 이미지 설명을 입력하십시오

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.