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 TPROXY-related Linux things #1025

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

Add TPROXY-related Linux things #1025

wants to merge 1 commit into from

Conversation

vi
Copy link
Contributor

@vi vi commented Feb 12, 2019

Should close #1023.

Depends on rust-lang/libc#1252

Example code:

extern crate nix;

use nix::sys::socket::{
    socket,
    AddressFamily,
    SockType,
    SockFlag,
    bind,
    SockAddr,
    InetAddr,
    IpAddr,
    recvmsg,
    MsgFlags,
    setsockopt,
    CmsgSpace,
    ControlMessage,
};
use nix::sys::socket::sockopt::{
    IpTransparent,
    RecvOrigDstAddrV6,
    RecvOrigDstAddrV4,
};
use nix::sys::uio::{
    IoVec,
};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let ipv6 = false;

    let family = if ipv6  { AddressFamily::Inet6 } else {  AddressFamily::Inet };
    let s = socket(family, SockType::Datagram, SockFlag::empty(), None)?;

    setsockopt(s, IpTransparent, &true)?;
    if !ipv6 {
        setsockopt(s, RecvOrigDstAddrV4, &true)?;
    } else {
        setsockopt(s, RecvOrigDstAddrV6, &true)?;
    }

    if !ipv6 {
        bind(s, &SockAddr::Inet(InetAddr::new(IpAddr::new_v4(127, 0, 0, 1), 1234)))?;
    } else {
        bind(s, &SockAddr::Inet(InetAddr::new(IpAddr::new_v6(0, 0, 0, 0,0,0,0,1), 1234)))?;
    }
    
    let mut buf = [0; 16];
    let iov = IoVec::from_mut_slice(&mut buf);
    let iovs = vec![iov];
    
    let mut da = CmsgSpace::new();
    let ret = recvmsg::<[u8;1280]>(s, &iovs[..], Some(&mut da), MsgFlags::empty())?;
    eprintln!("{:?}", ret);

    for x in ret.cmsgs() {
        match x {
            ControlMessage::OrigDstAddrV6(x) =>  {
                let sa = SockAddr::Inet(InetAddr::V6(x.clone()));
                eprintln!("{:?}", sa);
            },
            ControlMessage::OrigDstAddrV4(x) =>  {
                let sa = SockAddr::Inet(InetAddr::V4(x.clone()));
                eprintln!("{:?}", sa);
            },
            _ => eprintln!("?"),
        }
       
    }

    Ok(())
}

// iptables -t mangle -I PREROUTING -d 127.0.0.1 -p udp --dport 1235 -j TPROXY --on-port 1234 --on-ip 127.0.0.1

// ip6tables -t mangle -I PREROUTING -d ::1 -p udp --dport 1235 -j TPROXY --on-port 1234 --on-ip ::1

Copy link
Member

@asomers asomers left a comment

Choose a reason for hiding this comment

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

Github understands "Fixes" in commit messages, but I don't think it understands "Should close". You should change your commit message. And you'll need to rebase after PR #1020. Don't forget a CHANGELOG message.

@vi
Copy link
Contributor Author

vi commented Feb 12, 2019

Github understands "Fixes" in commit messages, but I don't think it understands "Should close".

It underlines the word "close" with a tooltip "This pull request closes issue #1023".

@vi
Copy link
Contributor Author

vi commented Jan 28, 2020

Is this feature needed in Nix? Shall I try to make it mergeable?

Copy link
Member

@asomers asomers left a comment

Choose a reason for hiding this comment

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

I think it's a worthwhile addition. Could you please enable it for FreeBSD too? It's been available since 12.0.

@vi
Copy link
Contributor Author

vi commented Jan 28, 2020

Is libc interface for FreeBSD for this feature exactly the same as in Linux?

@asomers
Copy link
Member

asomers commented Feb 2, 2020

This beings `OrigDstAddrV4` and `OrigDstAddrV6` `recvmsg` messages
and associated socket options
`RecvOrigDstAddrV4` and `RecvOrigDstAddrV6`.

Should close nix-rust#1023.
@vi
Copy link
Contributor Author

vi commented Feb 2, 2020

@asomers, What to use instead of SOL_IP for FreeBSD?

Or is trying to enable support of this on FreeBSD without actually testing it on a real FreeBSD is counterproductive?

@asomers
Copy link
Member

asomers commented Feb 4, 2020

For the level use IPPROTO_IP.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Feature request: Add Linux's IP_RECVORIGDSTADDR socket option and respective IP_ORIGDSTADDR control message.
2 participants