Commit 82776e24 authored by nanahira's avatar nanahira

first

parent febc13c2
# Project exclude paths # Project exclude paths
cmake-build-debug cmake-build-debug
.idea .idea
Dockerfile Dockerfile
\ No newline at end of file .dockerignore
/build
# Project exclude paths # Project exclude paths
cmake-build-debug cmake-build-debug
.idea .idea
.DS_Store .DS_Store
/build
stages:
- build
- combine
- deploy
variables:
GIT_DEPTH: "1"
CONTAINER_TEST_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
CONTAINER_TEST_ARM_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG-arm
CONTAINER_TEST_X86_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG-x86
CONTAINER_RELEASE_IMAGE: $CI_REGISTRY_IMAGE:latest
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
build-x86:
stage: build
tags:
- docker
script:
- TARGET_IMAGE=$CONTAINER_TEST_X86_IMAGE
- docker build --pull -t $TARGET_IMAGE .
- docker push $TARGET_IMAGE
build-arm:
stage: build
tags:
- docker-arm
script:
- TARGET_IMAGE=$CONTAINER_TEST_ARM_IMAGE
- docker build --pull -t $TARGET_IMAGE .
- docker push $TARGET_IMAGE
combine:
stage: combine
tags:
- docker
script:
- TARGET_IMAGE=$CONTAINER_TEST_IMAGE
- SOURCE_IMAGE_2=$CONTAINER_TEST_ARM_IMAGE
- SOURCE_IMAGE_1=$CONTAINER_TEST_X86_IMAGE
- docker pull $SOURCE_IMAGE_1
- docker pull $SOURCE_IMAGE_2
- docker manifest create $TARGET_IMAGE --amend $SOURCE_IMAGE_1 --amend
$SOURCE_IMAGE_2
- docker manifest push $TARGET_IMAGE
deploy_latest:
stage: deploy
tags:
- docker
script:
- TARGET_IMAGE=$CONTAINER_RELEASE_IMAGE
- SOURCE_IMAGE=$CONTAINER_TEST_IMAGE
- docker pull $SOURCE_IMAGE
- docker tag $SOURCE_IMAGE $TARGET_IMAGE
- docker push $TARGET_IMAGE
only:
- master
deploy_tag:
stage: deploy
tags:
- docker
script:
- TARGET_IMAGE=$CI_REGISTRY_IMAGE:$CI_COMMIT_TAG
- SOURCE_IMAGE=$CONTAINER_TEST_IMAGE
- docker pull $SOURCE_IMAGE
- docker tag $SOURCE_IMAGE $TARGET_IMAGE
- docker push $TARGET_IMAGE
only:
- tags
cmake_minimum_required(VERSION 3.21) cmake_minimum_required(VERSION 3.21)
project(tun) project(mctun)
set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD 23)
add_executable(tun main.cpp) add_executable(mctun main.cpp)
target_link_libraries(tun) target_link_libraries(mctun)
find_package(Threads REQUIRED) find_package(Threads REQUIRED)
target_link_libraries(tun Threads::Threads) target_link_libraries(mctun Threads::Threads)
#set(Boost_USE_STATIC_LIBS ON) #set(Boost_USE_STATIC_LIBS ON)
#find_package(Boost COMPONENTS program_options REQUIRED) #find_package(Boost COMPONENTS program_options REQUIRED)
......
FROM alpine:3.15 AS builder FROM debian:bullseye-slim as base
RUN apk --no-cache add build-base cmake linux-headers boost-dev boost-static RUN apt update && \
apt -y install build-essential libboost-dev iproute2 iptables ipset netcat-openbsd && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /var/log/* /var/cache/*
FROM base as builder
WORKDIR /usr/src/app WORKDIR /usr/src/app
RUN apt update && apt -y install cmake && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /var/log/* /var/cache/*
COPY . . COPY . .
RUN cmake -DCMAKE_BUILD_TYPE=Debug . RUN cmake .
RUN make RUN make
FROM alpine FROM base
RUN apk --no-cache add libgcc libstdc++ COPY --from=builder /usr/src/app/mctun /usr/local/bin/
COPY --from=builder /usr/src/app/tun . COPY ./entrypoint.sh /entrypoint.sh
ENTRYPOINT ["./tun"] ENTRYPOINT ["/entrypoint.sh"]
CMD ["mctun"]
# MCTUN
MyCard tun
## env
#!/bin/bash
pid=0
run_stop() {
signalCode=$1
if [ -n "$DOWN_SCRIPT" ]; then
eval "$DOWN_SCRIPT"
fi
if [ $pid -ne 0 ]; then
kill "-$signalCode" "$pid"
wait "$pid"
fi
echo "Stopped"
exit $((128 + signalCode));
}
trap 'kill ${!}; run_stop 2' SIGTERM
trap 'kill ${!}; run_stop 15' SIGINT
echo "Started"
"$@" &
pid="$!"
# wait forever
while true
do
tail -f /dev/null & wait ${!}
done
...@@ -19,8 +19,6 @@ struct Meta { ...@@ -19,8 +19,6 @@ struct Meta {
unsigned short reversed; unsigned short reversed;
}; };
#define decrypt_package encrypt_package
unsigned char local_id; unsigned char local_id;
unsigned char remote_id; unsigned char remote_id;
sockaddr_in remote_addr{.sin_family = AF_INET}; sockaddr_in remote_addr{.sin_family = AF_INET};
...@@ -47,14 +45,24 @@ uint16_t csum(uint16_t *packet, int packlen) { ...@@ -47,14 +45,24 @@ uint16_t csum(uint16_t *packet, int packlen) {
return (uint16_t) ~sum; return (uint16_t) ~sum;
} }
char *secret; class Secret {
size_t secret_length; private:
char* key;
size_t length;
public:
Secret(char* key): key(key), length(strlen(key)) {}
void encrypt(unsigned char* data, size_t length) {
for (size_t i = 0; i < length; i++) {
data[i] ^= key[i % this->length];
}
}
void decrypt(unsigned char* data, size_t length) {
encrypt(data, length);
}
};
void encrypt_package(unsigned char *buffer, size_t length) { Secret *localSecret;
for (auto i = 0; i < length; i++) { Secret *remoteSecret;
buffer[i] ^= secret[i % secret_length];
}
}
// internet -> tun // internet -> tun
void inbound(int raw, int tun) { void inbound(int raw, int tun) {
...@@ -70,7 +78,7 @@ void inbound(int raw, int tun) { ...@@ -70,7 +78,7 @@ void inbound(int raw, int tun) {
if (!(meta->src_id == remote_id && meta->dst_id == local_id && meta->reversed == 0)) continue; if (!(meta->src_id == remote_id && meta->dst_id == local_id && meta->reversed == 0)) continue;
auto inner = (iphdr *) (payload + sizeof(Meta)); auto inner = (iphdr *) (payload + sizeof(Meta));
auto payload_length = packet_length - overhead - sizeof(Meta); auto payload_length = packet_length - overhead - sizeof(Meta);
decrypt_package((unsigned char *) inner, payload_length); remoteSecret->decrypt((unsigned char *) inner, payload_length);
// if (ip_fast_csum(inner, inner->ihl)) continue; // if (ip_fast_csum(inner, inner->ihl)) continue;
if (csum((uint16_t *) inner, inner->ihl * 4)) continue; if (csum((uint16_t *) inner, inner->ihl * 4)) continue;
// std::cout << "packet_length " << packet_length // std::cout << "packet_length " << packet_length
...@@ -101,7 +109,7 @@ void outbound(int raw, int tun) { ...@@ -101,7 +109,7 @@ void outbound(int raw, int tun) {
while ((packet_length = read(tun, inner, sizeof(buffer) + sizeof(Meta))) >= 0) { while ((packet_length = read(tun, inner, sizeof(buffer) + sizeof(Meta))) >= 0) {
// std::cout << "sendto: " << inet_ntoa(remote_addr.sin_addr) << std::endl; // std::cout << "sendto: " << inet_ntoa(remote_addr.sin_addr) << std::endl;
if (!remote_addr.sin_addr.s_addr) continue; if (!remote_addr.sin_addr.s_addr) continue;
encrypt_package(inner, packet_length); localSecret->encrypt(inner, packet_length);
if (sendto(raw, buffer, packet_length + sizeof(Meta), 0, (sockaddr *) &remote_addr, sizeof(remote_addr)) < 0) { if (sendto(raw, buffer, packet_length + sizeof(Meta), 0, (sockaddr *) &remote_addr, sizeof(remote_addr)) < 0) {
perror("outbound write"); perror("outbound write");
} }
...@@ -109,30 +117,44 @@ void outbound(int raw, int tun) { ...@@ -109,30 +117,44 @@ void outbound(int raw, int tun) {
perror("outbound read"); perror("outbound read");
} }
int main(int argc, char *argv[]) { auto get_var(const char* varname, bool required = true) {
auto value = getenv(varname);
if (value == nullptr && required) {
std::cerr << "missing required environment variable: " << varname << std::endl;
exit(2);
}
return value;
}
local_id = atoi(getenv("local_id")); auto get_var_number(const char* varname, bool required = true) {
remote_id = atoi(getenv("remote_id")); auto value = get_var(varname, required);
auto endpoint = getenv("endpoint"); if (value == nullptr) return 0;
unsigned char proto = atoi(getenv("proto")); return atoi(value);
secret = getenv("secret"); }
auto dev = getenv("dev");
auto up = getenv("up"); int main(int argc, char *argv[]) {
local_id = get_var_number("LOCAL_ID", true);
remote_id = get_var_number("REMOTE_ID", true);
unsigned char proto = get_var_number("PROTO", true);
localSecret = new Secret(get_var("LOCAL_SECRET", true));
remoteSecret = new Secret(get_var("REMOTE_SECRET", true));
auto dev = get_var("DEV", true);
// optionals
auto up = get_var("UP_SCRIPT");
auto endpoint = get_var("ENDPOINT");
auto mark = get_var_number("MARK");
if (endpoint != nullptr) { if (endpoint != nullptr) {
auto he = gethostbyname(endpoint); auto he = gethostbyname(endpoint);
if (he == nullptr) { if (he == nullptr) {
perror("gethostbyname"); perror("gethostbyname error");
return -1; return -1;
} }
if (he->h_addr_list[0] == nullptr) { if (he->h_addr_list[0] == nullptr) {
perror("gethostbyname 2"); perror("gethostbyname error 2");
} }
remote_addr.sin_addr.s_addr = *(in_addr_t *) he->h_addr_list[0]; remote_addr.sin_addr.s_addr = *(in_addr_t *) he->h_addr_list[0];
} }
secret_length = strlen(secret);
ifreq ifr{}; ifreq ifr{};
ifr.ifr_flags = IFF_TUN | IFF_NO_PI; ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
strncpy(ifr.ifr_name, dev, IFNAMSIZ); strncpy(ifr.ifr_name, dev, IFNAMSIZ);
...@@ -142,6 +164,12 @@ int main(int argc, char *argv[]) { ...@@ -142,6 +164,12 @@ int main(int argc, char *argv[]) {
perror("socket init error"); perror("socket init error");
return -1; return -1;
} }
if (mark) {
if (setsockopt(raw, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) < 0) {
perror("setsockopt error");
return -1;
}
}
auto tun = open("/dev/net/tun", O_RDWR); auto tun = open("/dev/net/tun", O_RDWR);
if (tun < 0) { if (tun < 0) {
perror("tun init error"); perror("tun init error");
...@@ -163,4 +191,3 @@ int main(int argc, char *argv[]) { ...@@ -163,4 +191,3 @@ int main(int argc, char *argv[]) {
return 0; return 0;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment