Skip to content

Commit

Permalink
Basic support for freebsd ipfw firewall
Browse files Browse the repository at this point in the history
FreeBSD's ipfw firewall does not rewrite the destination
IP address when forwarding using rules such as:

 00100 fwd 127.0.0.1,2080 tcp from me to not me 80,443

This commit adds ipfw support by assuming transparent
redirection on freebsd. If you create the above rule and
point moproxy at a http proxy at IP address 1.2.3.4

 $ moproxy -b 127.0.0.1 -p 2080 -t 1.2.3.4:8080

You can fetch remote 443 or 80 ports without setting
proxy environment variables, eg:

 $ curl https://example.com:443
 <HTML>...
  • Loading branch information
stuart-mclaren committed Apr 5, 2023
1 parent 8a052ea commit d3f76c0
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 0 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,12 @@ nft add rule nat prerouting tcp dport {80, 443} redirect to 2080
# or the legacy iptables equivalent
iptables -t nat -A OUTPUT -p tcp -m multiport --dports 80,443 -j REDIRECT --to-port 2080
iptables -t nat -A PREROUTING -p tcp -m multiport --dports 80,443 -j REDIRECT --to-port 2080

# or ipfw (FreeBSD)
ipfw add 100 fwd 127.0.0.1,2080 tcp from me to not me dst-port 80,443
```


SOCKSv5 server is also launched alongs with transparent proxy on the same port:
```bash
http_proxy=socks5h://localhost:2080 curl ifconfig.co
Expand Down
9 changes: 9 additions & 0 deletions src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,12 @@ async fn accept_socks5(client: &mut TcpStream) -> io::Result<Destination> {
Ok((addr, port).into())
}

async fn transparent_dest(client: &mut TcpStream) -> io::Result<Destination> {
// Transparent firewall redirection (unmodified destination address)
// (for example, ipfw firewall with 'fwd' rule)
Ok((client.local_addr()?).into())
}

impl NewClient {
#[instrument(name = "retrieve_dest", skip_all)]
pub async fn from_socket(mut left: TcpStream, list: ServerList) -> io::Result<Self> {
Expand All @@ -152,6 +158,9 @@ impl NewClient {
#[cfg(not(target_os = "linux"))]
let dest: Option<SocketAddr> = None;

#[cfg(target_os = "freebsd")]
let dest = (transparent_dest(&mut left).await?).into();

let dest = if let Some(dest) = dest {
debug!(?dest, "Retrived destination via NAT info");
dest.into()
Expand Down

0 comments on commit d3f76c0

Please sign in to comment.