skcptun
skcptun은 C 언어와 Lua로 구현된 OpenWRT, Linux 및 MacOS용 암호화된 KCP 터널입니다.
상태
- "사용할 수 없는 것은 아닙니다"
- 현재는 Lua가 추가된 버전이며, 순수 C 버전은 더 이상 유지되지 않습니다.
특성
- 신뢰할 수 있는 UDP 암호화 터널을 기반으로 암호화된 전송 데이터에는 특성이 없습니다.
- 고속 모드와 일반 모드를 사용하여 네트워크 연결을 가속화하는 데 사용할 수 있습니다. 고속 모드의 측정된 전송 속도는 TCP 전송보다 훨씬 빠릅니다. (벤치마크)
- 현재 TUN 모드와 TCP 모드의 두 가지 모드를 지원합니다.
- TUN 모드에서는 클라이언트와 서버가 각각 동일한 네트워크 세그먼트에 가상 네트워크 카드를 생성합니다. 클라이언트는 기존 VPN 모드와 유사하게 암호화된 KCP 터널을 통해 모든 IP 패킷을 서버에 투명하게 전송합니다.
- TCP 모드에서는 클라이언트가 하나 이상의 포트를 수신하고 암호화된 KCP 터널을 통해 수신된 모든 데이터를 서버에 투명하게 전송합니다. 일반적으로 TUN 모드가 차단된 경우에 사용됩니다.
- Lua 스크립트를 사용하여 skcptun에서 제공하는 API를 기반으로 고유한 맞춤형 서비스를 구현할 수 있습니다.
설치하다
운영 환경: 리눅스, MacOS
종속 라이브러리: OpenSSL, libev
소스코드를 다운로드하고 압축을 푼 후:
cd skcptun
mkdir build
cd build
cmake ..
make
직접 복제하는 경우 하위 모듈을 업데이트해야 합니다.
git submodule update --init --recursive
환경 구성
TCP 모드
TUN 모드
- 가상 네트워크 카드 기술을 통해 터널이 구축되기 때문에 필요한 네트워크 설정이 필요합니다.
- Linux(Debian)를 예로 들면 커널은 tun 모듈을 지원해야 합니다. "modinfo tun" 명령으로 확인하세요.
- "iproute2" 및 "iptables" 툴킷이 설치되어 있어야 합니다.
섬기는 사람
- IP 전달을 활성화하고 "/etc/sysctl.conf" 파일에 다음 구성을 추가한 후 "sysctl -p"를 실행하여 적용합니다.
net.ipv4.ip_forward=1
net.ipv4.conf.all.route_localnet = 1
net.ipv4.conf.default.route_localnet = 1
net.ipv4.conf.[网卡接口].route_localnet = 1
net.ipv4.conf.lo.route_localnet = 1
net.ipv4.conf.[虚拟网卡接口].route_localnet = 1
- IP 전달을 켜고 기본 전달 정책 "iptables -P FORWARD ACCEPT"를 수정합니다.
- nat의 소스 주소를 송신 네트워크 카드 "iptables -t nat -A POSTROUTING -s 192.168.2.1/24 -o enp1s0 -j MASQUERADE"의 주소로 수정합니다.
고객
사용
- configfile은 구성 파일입니다.
- TUN 모드인 경우 실행하려면 루트 권한이 필요합니다.
구성 파일:
구성 파일은 Lua 파일입니다. "skcptun_config_sample"을 참조하세요. 내부에 주석이 있습니다.
skcptun에서 제공하는 내부 변수
SKT
"skt"는 "skt.conf.*", "skt.api.*" 및 "skt.cb.*"를 포함하여 Lua 스크립트에서 사용되는 내장 전역 변수입니다.
skcptun의 구성 정보
"skt.conf.*": skcptun이 Lua 스크립트에 노출하는 구성 정보 변수입니다.
skt.conf.tun_ip
가상 네트워크 카드, 클라이언트 및 서버의 IP는 "tun_client" 및 "tun_server" 모드에서 유효한 동일한 네트워크 세그먼트로 설정되어야 합니다.
skt.conf.tun_mask
가상 네트워크 카드의 서브넷 마스크, 클라이언트 및 서버 설정은 일관되며 "tun_client" 및 "tun_server" 모드에서 유효합니다.
skt.conf.skcp_serv_conf_list_size
"skcp_serv_conf"의 수입니다.
skt.conf.skcp_serv_conf_list[i].raw
i번째 "skcp_serv_conf" 자체 포인터는 매개변수를 API에 전달하는 데 사용됩니다.
skt.conf.skcp_serv_conf_list[i].addr
i번째 "skcp_serv_conf"의 IP 주소
skt.conf.skcp_serv_conf_list[i].port
i번째 "skcp_serv_conf"의 포트
skt.conf.skcp_serv_conf_list[i].key
i번째 "skcp_serv_conf"의 암호화된 문자열
skt.conf.skcp_serv_conf_list[i].ticket
i번째 "skcp_serv_conf" 클라이언트와 서버 간에 합의된 액세스 티켓은 "tun_client" 및 "proxy_client" 모드에서 유효합니다.
skt.conf.skcp_serv_conf_list[i].max_conn_cnt
"proxy_server" 및 "tun_server" 모드에서 유효한 i번째 "skcp_serv_conf"에 대한 최대 연결 수입니다.
skt.conf.skcp_cli_conf_list* 구성은 skt.conf.skcp_serv_conf_list*와 동일합니다.
skt.conf.etcp_serv_conf_list_size
"etcp_serv_conf_list"의 수
skt.conf.etcp_serv_conf_list[i].raw
tcp 서버 "etcp_serv_conf" 자체의 포인터는 매개변수를 API에 전달하는 데 사용됩니다.
skt.conf.etcp_serv_conf_list[i].addr
TCP 서버의 수신 주소입니다.
skt.conf.etcp_serv_conf_list[i].port
TCP 서버의 수신 대기 포트입니다.
skt.conf.etcp_cli_conf_list_size
"etcp_cli_conf_list"의 수
skt.conf.etcp_cli_conf_list[i].raw
TCP 클라이언트 "etcp_cli_conf" 자체의 포인터는 매개변수를 API에 전달하는 데 사용됩니다.
skt.conf.etcp_cli_conf_list[i].addr
"프록시 서버" 모드에서 유효한 TCP 클라이언트의 연결 주소입니다.
skt.conf.etcp_cli_conf_list[i].port
"프록시 서버" 모드에서 유효한 TCP 클라이언트의 연결 포트입니다.
skcptun에서 제공하는 내부 Lua API
"skt.api.*", skcptun이 Lua 스크립트에 공개하는 API입니다.
skt.api.skcp_init(conf, 루프, skcp_mode)
SKCP를 초기화합니다.
- 매개변수
- conf: skcp 구성
- loop: 이벤트 루프 객체
- skcp_mode: skcp 시작 모드, 정수, 1은 서버 모드, 2는 클라이언트 모드를 나타냅니다.
- 반환 값
- 실패하면 "nil, error_msg"가 반환됩니다.
- skcp 개체를 성공적으로 반환했습니다.
skt.api.skcp_free(skcp)
skcp를 파괴하고 해제합니다.
skt.api.skcp_req_cid(skcp, 티켓)
skcp 서버에서 연결 ID를 요청합니다.
- 매개변수
- SKCP 개체
- ticket: 구성 정보의 해당 티켓, 문자열
- 반환 값
- 실패하면 "nil, error_msg"가 반환됩니다.
- "확인"을 성공적으로 반환했습니다.
skt.api.skcp_send(skcp, cid, buf)
skcp를 통해 메시지를 보냅니다.
- 매개변수
- SKCP 개체
- cid: skcp의 연결 ID, 정수
- buf: 메시지 내용, 문자열
- 반환 값
- 실패하면 "nil, error_msg"가 반환됩니다.
- 성공적으로 전송된 바이트 수 >= 0, 정수를 성공적으로 반환합니다.
skt.api.skcp_close_conn(skcp, cid)
SKCP 연결을 닫습니다.
- 매개변수
- SKCP 개체
- cid: skcp의 연결 ID, 정수
- 반환 값
- 실패하면 "nil, error_msg"가 반환됩니다.
- 0을 성공적으로 반환합니다(정수).
skt.api.skcp_get_conn(skcp, cid)
SKCP 연결을 얻으세요.
- 매개변수
- SKCP 개체
- cid: skcp의 연결 ID, 정수
- 반환 값
- 실패하면 "nil, error_msg"가 반환됩니다.
- 성공 연결 개체
skt.api.etcp_server_init(conf, 루프)
etcp 서버를 초기화합니다.
- 매개변수
- conf: skcp 구성
- loop: 이벤트 루프 객체
- 반환 값
- 실패하면 "nil, error_msg"가 반환됩니다.
- etcp 서버 객체를 성공적으로 반환했습니다.
skt.api.etcp_server_free(etcp)
etcp 서버를 삭제하고 해제합니다.
skt.api.etcp_server_send(etcp, fd, buf)
etcp를 통해 클라이언트에게 메시지를 보냅니다.
- 매개변수
- etcp 서버 객체
- fd: 해당 fd, 정수
- buf: 메시지 내용, 문자열
- 반환 값
- 실패하면 "nil, error_msg"가 반환됩니다.
- 성공적으로 전송된 바이트 수 > 0, 정수를 성공적으로 반환합니다.
skt.api.etcp_server_get_conn(etcp, fd)
etcp 서버에 연결합니다.
- 매개변수
- 반환 값
- 실패하면 "nil, error_msg"가 반환됩니다.
- conn 객체를 성공적으로 반환했습니다.
skt.api.etcp_server_close_conn(etcp, fd, 자동)
etcp 서버 연결을 닫습니다.
- 매개변수
- etcp 서버 객체
- fd: 해당 fd, 정수
- 자동: 자동으로 닫힐지 여부입니다. 자동으로 닫히지 않으면 "on_close" 이벤트가 트리거됩니다. 1은 자동 종료를 의미하고, 0은 비자동 종료를 의미합니다.
- 반환 값: 없음
skt.api.etcp_client_init(conf, 루프)
etcp 클라이언트를 초기화합니다.
- 매개변수
- conf: skcp 구성
- loop: 이벤트 루프 객체
- 반환 값
- 실패하면 "nil, error_msg"가 반환됩니다.
- etcp 클라이언트 객체를 성공적으로 반환했습니다.
skt.api.etcp_client_free(etcp)
etcp 클라이언트를 삭제하고 해제합니다.
skt.api.etcp_client_send(etcp, fd, buf)
etcp를 통해 서버에 메시지를 보냅니다.
- 매개변수
- etcp 클라이언트 객체
- fd: 해당 fd, 정수
- buf: 메시지 내용, 문자열
- 반환 값
- 실패하면 "nil, error_msg"가 반환됩니다.
- 성공적으로 전송된 바이트 수 > 0, 정수를 성공적으로 반환합니다.
skt.api.etcp_client_create_conn(etcp, addr, 포트)
etcp 연결을 만듭니다.
- 매개변수
- etcp 클라이언트 객체
- addr: 서버 주소에 연결해야 함, 문자열
- 포트: 서버 포트에 연결해야 합니다.
- 반환 값
- 실패하면 "nil, error_msg"가 반환됩니다.
- 생성된 fd, 정수형을 성공적으로 반환했습니다.
skt.api.etcp_client_close_conn(etcp, fd)
etcp 클라이언트 연결을 닫습니다.
- 매개변수
- etcp 클라이언트 객체
- fd: 해당 fd, 정수
- 반환 값: 없음
skt.api.etcp_client_get_conn(etcp, fd)
etcp 클라이언트 연결을 얻으십시오.
- 매개변수
- etcp 클라이언트 객체
- fd: 해당 fd, 정수
- 반환 값
- 실패하면 "nil, error_msg"가 반환됩니다.
- conn 객체를 성공적으로 반환했습니다.
skt.api.tuntap_write(fd, buf)
가상 네트워크 카드에 데이터를 씁니다.
- 매개변수
- fd: 가상 네트워크 카드의 fd, 정수
- buf: 쓸 데이터, 문자열
- 반환 값
- 실패하면 "nil, error_msg"가 반환됩니다.
- 성공적으로 쓰여진 바이트 수, 정수
skt.api.get_from_skcp(skcp, 이름)
skcp 개체에서 해당 필드 값, 즉 "skcp.name"을 가져옵니다.
- 매개변수
- SKCP 개체
- 이름: skcp의 필드 이름, 현재는 "fd" 필드, 문자열만 지원합니다.
- 반환 값
- 실패하면 "nil, error_msg"가 반환됩니다.
- 이름에 해당하는 값을 성공적으로 반환합니다.
skt.api.get_ms()
현재 시스템에 대해 1970년 이후의 밀리초 수를 가져옵니다.
skt.api.hton32(i)
32비트 정수 변수를 호스트 바이트 순서에서 네트워크 바이트 순서로 변환합니다.
skt.api.ntoh32(i)
32비트 정수 변수를 네트워크 바이트 순서에서 호스트 바이트 순서로 변환합니다.
skt.api.band(a, b)
두 정수에 대해 비트 논리 AND 연산을 수행하고 결과를 반환합니다.
skt.api.bor(a, b)
두 정수에 대해 비트별 논리 OR 연산을 수행하고 결과를 반환합니다.
skt.api.bxor(a, b)
두 정수에 대해 비트별 XOR 연산을 수행하고 결과를 반환합니다.
skt.api.blshift(i, n)
정수를 n 비트만큼 왼쪽으로 이동하고 결과를 반환합니다.
skt.api.brshift(i, n)
정수를 n 비트만큼 오른쪽으로 이동하고 결과를 반환합니다.
skt.api.lookup_dns(도메인)
도메인 이름 확인
- 매개변수
- 반환 값
- 해당 IP를 점 형식(IPV4), 문자열로 반환합니다.
Lua 스크립트가 구현해야 하는 콜백 인터페이스
"skt.cb.*"는 skcptun 콜백의 다양한 시작 모드에 따라 다양한 인터페이스를 구현해야 합니다.
skt.cb.on_init(루프)
스크립트가 시작될 때 호출되는 첫 번째 콜백 인터페이스이며 한 번만 호출됩니다.
- 유효 범위: 모든 모드
- 매개변수
- 반환 값: 없음
skt.cb.on_skcp_accept(skcp, cid)
skcp 서버는 성공적으로 cid를 생성하고 각 연결에 대해 한 번만 호출됩니다.
- 유효한 범위: "proxy_server", "tun_server"
- 매개변수
- SKCP 개체
- cid: skcp의 연결 ID, 정수
- 반환 값: 없음
skt.cb.on_skcp_check_ticket(skcp,티켓)
Skcp 서버는 티켓이 올바른지 확인합니다.
- 유효한 범위: "proxy_server", "tun_server"
- 매개변수
- SKCP 객체
- ticket: 확인이 필요한 티켓, 문자열
- 반환 값:
- 확인에 성공하면 0을 반환합니다.
- 확인에 실패하면 0이 아닌 값이 반환됩니다.
skt.cb.on_skcp_recv_cid(skcp, cid)
skcp는 skcp 서버와의 연결이 성공적으로 설정되었음을 나타내는 cid를 받습니다. 즉, "skt.api.skcp_req_cid(skcp, ticket)"의 비동기 구조를 반환한다.
- 유효한 범위: "proxy_client", "tun_client"
- 매개변수
- SKCP 개체
- cid: skcp의 연결 ID, 정수
- 반환 값: 없음
skt.cb.on_skcp_recv_data(skcp, cid, buf)
skcp는 cid의 연결에 해당하는 데이터를 수신합니다.
- 유효 범위: 모든 모드
- 매개변수
- SKCP 개체
- cid: skcp의 연결 ID, 정수
- buf: 수신된 메시지 내용, 문자열
- 반환 값: 없음
skt.cb.on_skcp_close(skcp, cid)
skcp가 연결을 닫을 때 콜백은 일반적으로 시간 초과 또는 피어로부터 닫기 명령 수신으로 인해 발생할 수 있습니다. 현재 연결은 실제로 닫히지 않았습니다.
- 유효 범위: 모든 모드
- 매개변수
- SKCP 객체
- cid: skcp의 연결 ID, 정수
- 반환 값: 없음
skt.cb.on_tcp_accept(fd)
TCP 서버가 연결 요청을 받습니다.
- 유효한 범위: "proxy_client", "tun_client"
- 매개변수
- 반환 값: 없음
skt.cb.on_tcp_recv(fd, buf)
fd의 연결에 해당하는 tcp 데이터를 수신합니다.
- 유효 범위: 모든 모드
- 매개변수
- fd: 연결의 fd, 정수
- buf: 수신된 메시지 내용, 문자열
- 반환 값: 없음
skt.cb.on_tcp_close(fd)
fd에 해당하는 TCP 연결을 닫습니다. 현재 연결이 실제로 닫혀 있지 않습니다.
- 유효 범위: 모든 모드
- 매개변수
- 반환 값: 없음
skt.cb.on_tun_read(buf)
가상 네트워크 카드로부터 데이터를 받습니다.
- 유효한 범위: "tun_client", "tun_server"
- 매개변수
- 반환 값: 없음
skt.cb.on_beat()
매초마다 호출을 트리거합니다.
- 유효한 범위: "proxy_client", "tun_client"
- 매개변수: 없음
- 반환 값: 없음
시험
환경
- 서버:리눅스/1C/1G
- 클라이언트:MacOS/8C/8G
- 네트워크 상태, 핑 값:
21 packets transmitted, 20 packets received, 4.8% packet loss
round-trip min/avg/max/stddev = 159.492/164.087/171.097/3.232 ms
프로세스 데이터(RTT)
- 연결 수: 1, 데이터 패킷: 1000, 전송 간격: 100ms
TCP RTT:
------------
Min = 161.0
Max = 1239.0
Average = 293.956
NR = 1000
Skcptun RTT:
------------
Min = 160.0
Max = 487.0
Average = 181.618
NR = 1000
- 연결 수: 10, 데이터 패킷: 1000, 전송 간격: 100ms
TCP RTT:
------------
Min = 159.0
Max = 1076.0
Average = 262.500
NR = 10000
Skcptun RTT:
------------
Min = 159.0
Max = 534.0
Average = 174.251
NR = 10000
결론적으로
- 동일한 네트워크 환경에서 속도 개선 효과는 약 30~40% 정도입니다.
알아채다
- 이제 막 작성이 끝났고 개인용으로 기능은 완벽히 완성되었습니다
- 암호화 sock5 프록시를 가속화하는 데 사용하지 마십시오.