mirror of
https://github.com/dndx/phantun.git
synced 2025-09-16 04:04:29 +08:00
Compare commits
6 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
9ff691d063 | ||
|
b5e79653f0 | ||
|
f496a7919b | ||
|
bf6b9bc2ff | ||
|
47b9037968 | ||
|
c2341b6662 |
4
.github/workflows/release.yml
vendored
4
.github/workflows/release.yml
vendored
@@ -26,9 +26,9 @@ jobs:
|
||||
- aarch64-unknown-linux-gnu
|
||||
- aarch64-unknown-linux-musl
|
||||
- mips-unknown-linux-gnu
|
||||
- mips-unknown-linux-musl
|
||||
#- mips-unknown-linux-musl # currently does not build due to libc::sock_txtime not found, need a newer release of libc
|
||||
- mipsel-unknown-linux-gnu
|
||||
- mipsel-unknown-linux-musl
|
||||
#- mipsel-unknown-linux-musl
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
14
README.md
14
README.md
@@ -35,7 +35,7 @@ Table of Contents
|
||||
|
||||
# Latest release
|
||||
|
||||
[v0.4.1](https://github.com/dndx/phantun/releases/tag/v0.4.1)
|
||||
[v0.4.2](https://github.com/dndx/phantun/releases/tag/v0.4.2)
|
||||
|
||||
# Overview
|
||||
|
||||
@@ -73,8 +73,8 @@ It is also assumed that **Phantun Client** listens for incoming UDP packets at
|
||||
(the `--remote` option for client).
|
||||
|
||||
Phantun creates TUN interface for both the Client and Server. For **Client**, Phantun assigns itself the IP address
|
||||
`192.168.200.2` and `fec8::2` by default.
|
||||
For **Server**, it assigns `192.168.201.2` and `fec9::2` by default. Therefore, your Kernel must have
|
||||
`192.168.200.2` and `fcc8::2` by default.
|
||||
For **Server**, it assigns `192.168.201.2` and `fcc9::2` by default. Therefore, your Kernel must have
|
||||
IPv4/IPv6 forwarding enabled and setup appropriate iptables/nftables rules for NAT between your physical
|
||||
NIC address and Phantun's Tun interface address.
|
||||
|
||||
@@ -83,11 +83,11 @@ run the executable with `-h` options to see how to change them.
|
||||
|
||||
Another way to help understand this network topology (please see the diagram above for an illustration of this topology):
|
||||
|
||||
Phantun Client is like a machine with private IP address (`192.168.200.2`/`fec8::2`) behind a router.
|
||||
Phantun Client is like a machine with private IP address (`192.168.200.2`/`fcc8::2`) behind a router.
|
||||
In order for it to reach the Internet, you will need to SNAT the private IP address before it's traffic
|
||||
leaves the NIC.
|
||||
|
||||
Phantun Server is like a server with private IP address (`192.168.201.2`/`fec9::2`) behind a router.
|
||||
Phantun Server is like a server with private IP address (`192.168.201.2`/`fcc9::2`) behind a router.
|
||||
In order to access it from the Internet, you need to `DNAT` it's listening port on the router
|
||||
and change the destination IP address to where the server is listening for incoming connections.
|
||||
|
||||
@@ -166,7 +166,7 @@ table inet nat {
|
||||
chain prerouting {
|
||||
type nat hook prerouting priority dstnat; policy accept;
|
||||
iif eth0 tcp dport 4567 dnat ip to 192.168.201.2
|
||||
iif eth0 tcp dport 4567 dnat ip6 to fec9::2
|
||||
iif eth0 tcp dport 4567 dnat ip6 to fcc9::2
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -177,7 +177,7 @@ table inet nat {
|
||||
|
||||
```
|
||||
iptables -t nat -A PREROUTING -p tcp -i eth0 --dport 4567 -j DNAT --to-destination 192.168.201.2
|
||||
ip6tables -t nat -A PREROUTING -p tcp -i eth0 --dport 4567 -j DNAT --to-destination fec9::2
|
||||
ip6tables -t nat -A PREROUTING -p tcp -i eth0 --dport 4567 -j DNAT --to-destination fcc9::2
|
||||
```
|
||||
|
||||
[Back to TOC](#table-of-contents)
|
||||
|
@@ -16,7 +16,7 @@ benchmark = []
|
||||
|
||||
[dependencies]
|
||||
bytes = "1"
|
||||
pnet = "0.29"
|
||||
pnet = "0.30"
|
||||
tokio = { version = "1.14", features = ["full"] }
|
||||
rand = { version = "0.8", features = ["small_rng"] }
|
||||
log = "0.4"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "phantun"
|
||||
version = "0.4.2"
|
||||
version = "0.5.0"
|
||||
edition = "2021"
|
||||
authors = ["Datong Sun <dndx@idndx.com>"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
@@ -21,4 +21,4 @@ pretty_env_logger = "0.4"
|
||||
tokio-tun = "0.5"
|
||||
num_cpus = "1.13"
|
||||
neli = "0.6"
|
||||
nix = "0.23"
|
||||
nix = "0.24"
|
||||
|
@@ -4,6 +4,7 @@ use fake_tcp::{Socket, Stack};
|
||||
use log::{debug, error, info};
|
||||
use phantun::utils::{assign_ipv6_address, new_udp_reuseport};
|
||||
use std::collections::HashMap;
|
||||
use std::fs;
|
||||
use std::io;
|
||||
use std::net::{Ipv4Addr, SocketAddr};
|
||||
use std::sync::Arc;
|
||||
@@ -97,6 +98,17 @@ async fn main() -> io::Result<()> {
|
||||
.default_value("fcc8::2")
|
||||
.takes_value(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("handshake_packet")
|
||||
.long("handshake-packet")
|
||||
.required(false)
|
||||
.value_name("PATH")
|
||||
.help("Specify a file, which, after TCP handshake, its content will be sent as the \
|
||||
first data packet to the server.\n\
|
||||
Note: ensure this file's size does not exceed the MTU of the outgoing interface. \
|
||||
The content is always sent out in a single packet and will not be further segmented")
|
||||
.takes_value(true),
|
||||
)
|
||||
.get_matches();
|
||||
|
||||
let local_addr: SocketAddr = matches
|
||||
@@ -139,6 +151,10 @@ async fn main() -> io::Result<()> {
|
||||
};
|
||||
|
||||
let tun_name = matches.value_of("tun").unwrap();
|
||||
let handshake_packet: Option<Vec<u8>> = matches
|
||||
.value_of("handshake_packet")
|
||||
.map(fs::read)
|
||||
.transpose()?;
|
||||
|
||||
let num_cpus = num_cpus::get();
|
||||
info!("{} cores available", num_cpus);
|
||||
@@ -186,9 +202,17 @@ async fn main() -> io::Result<()> {
|
||||
}
|
||||
|
||||
let sock = Arc::new(sock.unwrap());
|
||||
if let Some(ref p) = handshake_packet {
|
||||
if sock.send(p).await.is_none() {
|
||||
error!("Failed to send handshake packet to remote, closing connection.");
|
||||
continue;
|
||||
}
|
||||
|
||||
debug!("Sent handshake packet to: {}", sock);
|
||||
}
|
||||
|
||||
// send first packet
|
||||
let res = sock.send(&buf_r[..size]).await;
|
||||
if res.is_none() {
|
||||
if sock.send(&buf_r[..size]).await.is_none() {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@@ -3,6 +3,7 @@ use fake_tcp::packet::MAX_PACKET_LEN;
|
||||
use fake_tcp::Stack;
|
||||
use log::{debug, error, info};
|
||||
use phantun::utils::{assign_ipv6_address, new_udp_reuseport};
|
||||
use std::fs;
|
||||
use std::io;
|
||||
use std::net::Ipv4Addr;
|
||||
use std::sync::Arc;
|
||||
@@ -97,6 +98,17 @@ async fn main() -> io::Result<()> {
|
||||
.default_value("fcc9::2")
|
||||
.takes_value(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("handshake_packet")
|
||||
.long("handshake-packet")
|
||||
.required(false)
|
||||
.value_name("PATH")
|
||||
.help("Specify a file, which, after TCP handshake, its content will be sent as the \
|
||||
first data packet to the client.\n\
|
||||
Note: ensure this file's size does not exceed the MTU of the outgoing interface. \
|
||||
The content is always sent out in a single packet and will not be further segmented")
|
||||
.takes_value(true),
|
||||
)
|
||||
.get_matches();
|
||||
|
||||
let local_port: u16 = matches
|
||||
@@ -137,6 +149,10 @@ async fn main() -> io::Result<()> {
|
||||
};
|
||||
|
||||
let tun_name = matches.value_of("tun").unwrap();
|
||||
let handshake_packet: Option<Vec<u8>> = matches
|
||||
.value_of("handshake_packet")
|
||||
.map(fs::read)
|
||||
.transpose()?;
|
||||
|
||||
let num_cpus = num_cpus::get();
|
||||
info!("{} cores available", num_cpus);
|
||||
@@ -169,6 +185,14 @@ async fn main() -> io::Result<()> {
|
||||
loop {
|
||||
let sock = Arc::new(stack.accept().await);
|
||||
info!("New connection: {}", sock);
|
||||
if let Some(ref p) = handshake_packet {
|
||||
if sock.send(p).await.is_none() {
|
||||
error!("Failed to send handshake packet to remote, closing connection.");
|
||||
continue;
|
||||
}
|
||||
|
||||
debug!("Sent handshake packet to: {}", sock);
|
||||
}
|
||||
|
||||
let packet_received = Arc::new(Notify::new());
|
||||
let quit = CancellationToken::new();
|
||||
|
Reference in New Issue
Block a user