Commit d70d4b10 authored by nanamicat's avatar nanamicat

docker

parent 474d54a0
FROM rust:alpine as builder
WORKDIR /usr/src/app
COPY . .
RUN cargo install --path .
FROM alpine
RUN apk --no-cache add libgcc libstdc++ bash iproute2 iptables ipset netcat-openbsd
COPY --from=builder /usr/local/cargo/bin/tun1 /usr/local/bin/tun
COPY ./entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
CMD ["tun"]
use pnet::packet::ipv4::Ipv4Packet;
use pnet::packet::Packet;
use socket2::{Domain, Protocol, SockAddr, Socket, Type};
use socket2::{Domain, Protocol, Socket, Type};
use std::error::Error;
use std::io::{BufRead, Read, Write};
use std::mem::{transmute, MaybeUninit};
use std::sync::{Arc, Mutex};
use std::io::{Read, Write};
use std::mem::{size_of, MaybeUninit};
use std::net::ToSocketAddrs;
use std::process::Command;
use std::sync::{Arc, RwLock};
use std::{env, thread};
use std::net::{SocketAddr, SocketAddrV4};
use std::net::UdpSocket;
#[repr(C)]
pub struct Meta {
......@@ -23,17 +20,16 @@ struct Secret {
}
impl Secret {
fn new(key: &String) -> Secret {
Secret {
fn new(key: &str) -> Self {
Self {
key: key.as_bytes().to_vec(),
}
}
fn encrypt(&self, data: &mut [u8]) {
for (i, byte) in data.iter_mut().enumerate() {
*byte ^= self.key[i % self.key.len()];
for (i, b) in data.iter_mut().enumerate() {
*b ^= self.key[i % self.key.len()];
}
}
fn decrypt(&self, data: &mut [u8]) {
self.encrypt(data);
}
......@@ -44,108 +40,136 @@ fn main() -> Result<(), Box<dyn Error>> {
let remote_id: u8 = env::var("REMOTE_ID")?.parse()?;
let local_secret = Secret::new(&env::var("LOCAL_SECRET")?);
let remote_secret = Secret::new(&env::var("REMOTE_SECRET")?);
let remote_addr: Arc<Mutex<Option<SockAddr>>> = Arc::new(Mutex::new(
match env::var("REMOTE_ADDR") {
let proto: i32 = env::var("PROTO")?.parse()?;
let up = env::var("UP_SCRIPT")?;
let dev = env::var("DEV")?;
let family = if env::var("FAMILY")?.parse::<u8>()? == 6 {
Domain::IPV6
} else {
Domain::IPV4
};
let endpoint = Arc::new(RwLock::new(match env::var("ENDPOINT") {
Ok(addr_str) => {
let parsed = addr_str.parse::<SocketAddr>()?;
let parsed = addr_str.to_socket_addrs()?.next().unwrap();
Some(parsed.into())
}
Err(_) => None,
}
));
}));
let mut config = tun::Configuration::default();
config
.address((10, 0, 0, local_id))
.netmask((255, 255, 255, 0))
.destination((10, 0, 0, remote_id))
.up();
#[cfg(target_os = "linux")]
config.platform_config(|config| {
config.ensure_root_privileges(true);
});
config.tun_name(dev).up();
let dev = tun::create(&config)?;
let (mut reader, mut writer) = dev.split();
// 创建用于接收的原始套接字,协议号为 144
let socket = Socket::new(Domain::IPV4, Type::RAW, Some(Protocol::from(144)))?;
let socket_arc = Arc::new(Mutex::new(socket));
let socket_for_inbound = Arc::clone(&socket_arc);
// Create a raw socket with protocol number 144
let socket = Socket::new(family, Type::RAW, Some(Protocol::from(proto)))?;
#[cfg(target_os = "linux")]
socket.set_mark(env::var("MARK")?.parse()?);
let socket_clone = socket.try_clone()?;
let remote_addr_clone = Arc::clone(&remote_addr);
match Command::new(up).status() {
Ok(status) => {
if !status.success() {
eprintln!("Script exited with non-zero status: {}", status);
}
}
Err(e) => eprintln!("Failed to run script '{}'", e),
}
let inbound = thread::spawn(move || {
// Thread for receiving from WAN (raw socket) and writing to TUN
let inbound = {
let remote_addr = Arc::clone(&endpoint);
let local_secret = local_secret;
thread::spawn(move || {
let mut recv_buf = [MaybeUninit::uninit(); 1500];
loop {
let sock_guard = socket_for_inbound.lock().unwrap();
match sock_guard.recv_from(&mut recv_buf) {
Ok((len, addr1)) => {
println!("recv from {:?}", recv_buf);
let recv_buf2: &mut [u8] = unsafe { transmute(&mut recv_buf[..len]) };
if let Some(packet) = Ipv4Packet::new(recv_buf2) {
let header_length = packet.get_header_length() as usize * 4;
let (header, data) = recv_buf2.split_at_mut(header_length);
let (meta1, payload) = data.split_at_mut(size_of::<Meta>());
let meta: &Meta = unsafe { transmute(&meta1) };
if meta.src_id == remote_id && meta.dst_id == local_id && meta.reversed == 0
match socket.recv_from(&mut recv_buf) {
Ok((len, addr)) => {
// Safely interpret the uninit buffer up to `len` as bytes
let data = unsafe {
std::slice::from_raw_parts_mut(recv_buf.as_mut_ptr() as *mut u8, len)
};
if let Some(packet) = Ipv4Packet::new(data) {
let header_len = packet.get_header_length() as usize * 4;
let (_ip_header, rest) = data.split_at_mut(header_len);
if rest.len() < size_of::<Meta>() {
// Malformed packet
continue;
}
let (meta_bytes, payload) = rest.split_at_mut(size_of::<Meta>());
// Extract meta
let meta = Meta {
src_id: meta_bytes[0],
dst_id: meta_bytes[1],
reversed: u16::from_le_bytes([meta_bytes[2], meta_bytes[3]]),
};
// Check if it matches our expected IDs
if meta.src_id == remote_id
&& meta.dst_id == local_id
&& meta.reversed == 0
{
let mut addr_lock = remote_addr_clone.lock().unwrap();
*addr_lock = Some(addr1);
// Update remote address for outbound
*remote_addr.write().unwrap() = Some(addr);
// Decrypt and push into TUN
local_secret.decrypt(payload);
writer.write(payload);
}
let _ = writer.write_all(payload);
} else {
// eprintln!("Dropping unexpected packet");
}
}
Err(e) => {
eprintln!("接收数据包时出错: {:?}", e);
}
Err(e) => eprintln!("Error receiving: {}", e),
}
}
});
})
};
let outbound = thread::spawn(move || {
let mut recv_buf = [0u8; 1500 - 20];
// Thread for reading from TUN, encrypting, and sending to WAN
let outbound = {
let remote_addr = Arc::clone(&endpoint);
let remote_secret = remote_secret;
thread::spawn(move || {
let mut buffer = [0u8; 1500 - 20]; // minus typical IP header space
let meta_size = size_of::<Meta>();
// Pre-initialize with our Meta header (local -> remote)
let meta = Meta {
src_id: local_id,
dst_id: remote_id,
reversed: 0,
};
let meta_size = size_of::<Meta>();
unsafe {
// Turn the Meta struct into bytes
let meta_bytes =
std::slice::from_raw_parts(&meta as *const Meta as *const u8, meta_size);
recv_buf[..meta_size].copy_from_slice(meta_bytes);
}
unsafe { std::slice::from_raw_parts(&meta as *const Meta as *const u8, meta_size) };
buffer[..meta_size].copy_from_slice(meta_bytes);
loop {
match reader.read(&mut recv_buf[meta_size..]) {
Ok(len) => {
println!("recv from {:?}", &recv_buf[meta_size..meta_size + len]);
let maybe_remote = remote_addr.lock().unwrap().clone();
println!("1");
if let Some(ref remote) = maybe_remote {
println!("2");
let sock_guard = socket_arc.lock().unwrap();
println!("3");
remote_secret.encrypt(&mut recv_buf[meta_size..meta_size + len]);
println!("4");
if let Err(e) = sock_guard.send_to(&recv_buf[..meta_size + len], remote) {
println!("5");
eprintln!("Error sending packet: {:?}", e);
match reader.read(&mut buffer[meta_size..]) {
Ok(n) if n > 0 => {
// If we have a known remote address, encrypt and send
if let Some(ref addr) = *remote_addr.read().unwrap() {
remote_secret.encrypt(&mut buffer[meta_size..meta_size + n]);
if let Err(e) = socket_clone.send_to(&buffer[..meta_size + n], addr) {
eprintln!("Error sending packet: {}", e);
}
} else {
eprintln!("No remote address available; packet discarded.");
eprintln!("No remote address set; packet dropped.");
}
}
Err(_) => {}
Err(e) => eprintln!("Error reading from TUN: {}", e),
_ => {}
}
}
});
inbound.join();
outbound.join();
})
};
let _ = inbound.join();
let _ = outbound.join();
Ok(())
}
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