Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pcap analysis to XRay #14

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ jobs:
steps:
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f # v1.0.6
- if: matrix.os == 'ubuntu-24.04'
run: sudo apt-get install -y libpcap-dev
- name: Install hack
run: cargo +stable install --git https://github.com/taiki-e/cargo-hack.git cargo-hack --rev c0b517b9eefa27cdaf27cca5f1b186c00ef1af47 --locked
- run: cargo hack test --each-feature ${{ matrix.packages }}
Expand All @@ -29,6 +31,8 @@ jobs:
steps:
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f # v1.0.6
- if: matrix.os == 'ubuntu-24.04'
run: sudo apt-get install -y libpcap-dev
- run: CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER='sudo -E' cargo test -- --ignored

crypto-bench:
Expand Down
117 changes: 110 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions neptun/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ default = []
device = ["socket2", "thiserror"]
# mocks std::time::Instant with mock_instant
mock-instant = ["mock_instant"]
xray = []

[dependencies]
base64 = "0.13"
Expand Down
35 changes: 35 additions & 0 deletions neptun/src/noise/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,41 @@ impl Tunn {
self.handle_verified_packet(packet, dst)
}

#[cfg(feature = "xray")]
pub fn decrypt<'a>(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So you can only use this while tunnel is "hot" right ?
Basicaly we have a 180s * 3 (you can see in timers)
I guess this is fine for now, but would be nice if we could rebuild everything from packet's in long past :D, let's at minimum have a jira ticket to track it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had this thought too but didn't really want to dig into it, but it's a good idea 😄 Created LLT-5881 for it

&mut self,
datagram: &[u8],
dst: &'a mut [u8],
) -> Result<&'a [u8], WireGuardError> {
let packet = Tunn::parse_incoming_packet(datagram)?;
match packet {
Packet::PacketData(p) => {
let r_idx = p.receiver_idx as usize;
let idx = r_idx % N_SESSIONS;

// Get the (probably) right session
let decapsulated_packet = {
let session = self.sessions[idx].as_ref();
let session = session.ok_or_else(|| {
tracing::trace!(
message = "No current session available",
remote_idx = r_idx
);
WireGuardError::NoCurrentSession
})?;
session.decrypt_data_packet(p, dst)?
};

match self.validate_decapsulated_packet(decapsulated_packet) {
TunnResult::WriteToTunnelV4(p, _) => Ok(p),
TunnResult::Err(err) => Err(err),
_ => Err(WireGuardError::UnexpectedPacket),
}
}
_ => Err(WireGuardError::WrongPacketType),
}
}

pub(crate) fn handle_verified_packet<'a>(
&mut self,
packet: Packet,
Expand Down
35 changes: 35 additions & 0 deletions neptun/src/noise/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,41 @@ impl Session {
let counter_validator = self.receiving_key_counter.lock();
(counter_validator.next, counter_validator.receive_cnt)
}

#[cfg(feature = "xray")]
pub fn decrypt_data_packet<'a>(
&self,
packet: PacketData,
dst: &'a mut [u8],
) -> Result<&'a mut [u8], WireGuardError> {
let ct_len = packet.encrypted_encapsulated_packet.len();
if dst.len() < ct_len {
// This is a very incorrect use of the library, therefore panic and not error
panic!("The destination buffer is too small");
}
let decrypt_key = if packet.receiver_idx == self.receiving_index {
&self.receiver
} else if packet.receiver_idx == self.sending_index {
&self.sender
} else {
return Err(WireGuardError::WrongIndex);
};

let ret = {
let mut nonce = [0u8; 12];
nonce[4..12].copy_from_slice(&packet.counter.to_le_bytes());
dst[..ct_len].copy_from_slice(packet.encrypted_encapsulated_packet);
decrypt_key
.open_in_place(
Nonce::assume_unique_for_key(nonce),
Aad::from(&[]),
&mut dst[..ct_len],
)
.map_err(|_| WireGuardError::InvalidAeadTag)?
};

Ok(ret)
}
}

#[inline(always)]
Expand Down
4 changes: 3 additions & 1 deletion xray/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ clap = { version = "4.5", features = ["derive"] }
color-eyre = "0.6"
csv = "1.3.1"
curve25519-dalek = "4.1"
pcap = "2.2"
pnet = "0.35"
rand = "0.8.5"
serde = { version = "1.0", features = ["derive"] }
thiserror = "1.0"
tokio = { version = "1.41", features = ["macros", "rt-multi-thread", "time", "net", "sync"] }
x25519-dalek = "2.0"

[dependencies.neptun]
version = "0.6.0"
path = "../neptun"
features = ["device"]
features = ["device", "xray"]
1 change: 0 additions & 1 deletion xray/Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ name = "pypi"
[packages]
ruff = "==0.8"
matplotlib = "==3.9"
scapy = "==2.6"

[dev-packages]

Expand Down
Loading
Loading