mirror of
https://github.com/shadowsocks/shadowsocks-rust.git
synced 2026-02-09 01:59:16 +08:00
82
configs/iptables_mixed.sh
Normal file
82
configs/iptables_mixed.sh
Normal file
@@ -0,0 +1,82 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo "This script must be run as root" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
## TCP
|
||||
# NAT PREROUTING
|
||||
iptables -t nat -N shadowsocks-nat
|
||||
# Skip LoopBack, Reserved
|
||||
iptables -t nat -A shadowsocks-nat -d 0/8 -j RETURN
|
||||
iptables -t nat -A shadowsocks-nat -d 127/8 -j RETURN
|
||||
iptables -t nat -A shadowsocks-nat -d 10/8 -j RETURN
|
||||
iptables -t nat -A shadowsocks-nat -d 169.254/16 -j RETURN
|
||||
iptables -t nat -A shadowsocks-nat -d 172.16/12 -j RETURN
|
||||
iptables -t nat -A shadowsocks-nat -d 192.168/16 -j RETURN
|
||||
iptables -t nat -A shadowsocks-nat -d 224/4 -j RETURN
|
||||
iptables -t nat -A shadowsocks-nat -d 240/4 -j RETURN
|
||||
# Bypass CN IPs
|
||||
iptables -t nat -A shadowsocks-nat -m set --match-set cn dst -j RETURN
|
||||
# Bypass sslocal's outbound data
|
||||
iptables -t nat -A shadowsocks-nat -m mark --mark 255 -j RETURN
|
||||
# Redirect TCP to 60080
|
||||
iptables -t nat -A shadowsocks-nat -p tcp -j REDIRECT --to-ports 60080
|
||||
# Local TCP -> shadowsocks-nat
|
||||
iptables -t nat -A OUTPUT -p tcp -j shadowsocks-nat
|
||||
# LAN TCP -> shadowsocks-nat
|
||||
iptables -t nat -A PREROUTING -p tcp -j shadowsocks-nat
|
||||
|
||||
## UDP
|
||||
# Strategy Route
|
||||
ip rule add fwmark 1 table 233
|
||||
ip route add local 0.0.0.0/0 dev lo table 233
|
||||
|
||||
# TPROXY for LAN
|
||||
iptables -t mangle -N shadowsocks-tproxy
|
||||
# Skip LoopBack, Reserved
|
||||
iptables -t mangle -A shadowsocks-tproxy -d 0/8 -j RETURN
|
||||
iptables -t mangle -A shadowsocks-tproxy -d 127/8 -j RETURN
|
||||
iptables -t mangle -A shadowsocks-tproxy -d 10/8 -j RETURN
|
||||
iptables -t mangle -A shadowsocks-tproxy -d 169.254/16 -j RETURN
|
||||
iptables -t mangle -A shadowsocks-tproxy -d 172.16/12 -j RETURN
|
||||
iptables -t mangle -A shadowsocks-tproxy -d 192.168/16 -j RETURN
|
||||
iptables -t mangle -A shadowsocks-tproxy -d 224/4 -j RETURN
|
||||
iptables -t mangle -A shadowsocks-tproxy -d 240/4 -j RETURN
|
||||
# Bypass CN IPs
|
||||
iptables -t mangle -A shadowsocks-tproxy -m set --match-set cn dst -j RETURN
|
||||
# Bypass sslocal's outbound data
|
||||
iptables -t mangle -A shadowsocks-tproxy -m mark --mark 255 -j RETURN
|
||||
# TPROXY UDP to 60080
|
||||
iptables -t mangle -A shadowsocks-tproxy -p udp -j TPROXY --on-port 60080 --tproxy-mark 1/1
|
||||
#iptables -t mangle -A shadowsocks-tproxy -p tcp -j TPROXY --on-port 60080 --tproxy-mark 1/1
|
||||
# Apply TPROXY to LAN
|
||||
iptables -t mangle -A PREROUTING -p udp -j shadowsocks-tproxy
|
||||
|
||||
# TPROXY for Local
|
||||
iptables -t mangle -N shadowsocks-tproxy-mark
|
||||
# Skip LoopBack, Reserved
|
||||
iptables -t mangle -A shadowsocks-tproxy-mark -d 127/8 -j RETURN
|
||||
iptables -t mangle -A shadowsocks-tproxy-mark -d 10/8 -j RETURN
|
||||
iptables -t mangle -A shadowsocks-tproxy-mark -d 169.254/16 -j RETURN
|
||||
iptables -t mangle -A shadowsocks-tproxy-mark -d 172.16/12 -j RETURN
|
||||
iptables -t mangle -A shadowsocks-tproxy-mark -d 192.168/16 -j RETURN
|
||||
iptables -t mangle -A shadowsocks-tproxy-mark -d 224/4 -j RETURN
|
||||
iptables -t mangle -A shadowsocks-tproxy-mark -d 240/4 -j RETURN
|
||||
# Bypass CN IPs
|
||||
iptables -t mangle -A shadowsocks-tproxy-mark -m set --match-set cn dst -j RETURN
|
||||
# Bypass sslocal's outbound data
|
||||
iptables -t mangle -A shadowsocks-tproxy-mark -m mark --mark 255 -j RETURN
|
||||
# Set MARK and reroute
|
||||
iptables -t mangle -A shadowsocks-tproxy-mark -p udp -j MARK --set-xmark 1
|
||||
#iptables -t mangle -A shadowsocks-tproxy-mark -p tcp -j MARK --set-xmark 1
|
||||
# Apply TPROXY for Local
|
||||
iptables -t mangle -A OUTPUT -p udp -j shadowsocks-tproxy-mark
|
||||
|
||||
# DIVERT rules
|
||||
# For optimizing TCP
|
||||
# iptables -t mangle -N shadowsocks-divert
|
||||
# iptables -t mangle -A shadowsocks-divert -j MARK --set-mark 1
|
||||
# iptables -t mangle -A shadowsocks-divert -j ACCEPT
|
||||
# iptables -t mangle -I PREROUTING -p tcp -m socket -j shadowsocks-divert
|
||||
@@ -37,31 +37,31 @@ iptables -t mangle -A PREROUTING -j SS
|
||||
#ip6tables -t mangle -A PREROUTING -j SS
|
||||
|
||||
# OUTPUT rules
|
||||
iptables -t mangle -N SS-MASK
|
||||
#ip6tables -t mangle -N SS-MASK
|
||||
iptables -t mangle -N SS-MARK
|
||||
#ip6tables -t mangle -N SS-MARK
|
||||
# Reserved addresses
|
||||
iptables -t mangle -A SS-MASK -d 0/8 -j RETURN
|
||||
iptables -t mangle -A SS-MASK -d 127/8 -j RETURN
|
||||
iptables -t mangle -A SS-MASK -d 10/8 -j RETURN
|
||||
iptables -t mangle -A SS-MASK -d 169.254/16 -j RETURN
|
||||
iptables -t mangle -A SS-MASK -d 172.16/12 -j RETURN
|
||||
iptables -t mangle -A SS-MASK -d 192.168/16 -j RETURN
|
||||
iptables -t mangle -A SS-MASK -d 224/4 -j RETURN
|
||||
iptables -t mangle -A SS-MASK -d 240/4 -j RETURN
|
||||
#ip6tables -t mangle -A SS-MASK -d ::1/128 -j RETURN
|
||||
#ip6tables -t mangle -A SS-MASK -d fc00::/7 -j RETURN
|
||||
#ip6tables -t mangle -A SS-MASK -d fe80::/10 -j RETURN
|
||||
iptables -t mangle -A SS-MARK -d 0/8 -j RETURN
|
||||
iptables -t mangle -A SS-MARK -d 127/8 -j RETURN
|
||||
iptables -t mangle -A SS-MARK -d 10/8 -j RETURN
|
||||
iptables -t mangle -A SS-MARK -d 169.254/16 -j RETURN
|
||||
iptables -t mangle -A SS-MARK -d 172.16/12 -j RETURN
|
||||
iptables -t mangle -A SS-MARK -d 192.168/16 -j RETURN
|
||||
iptables -t mangle -A SS-MARK -d 224/4 -j RETURN
|
||||
iptables -t mangle -A SS-MARK -d 240/4 -j RETURN
|
||||
#ip6tables -t mangle -A SS-MARK -d ::1/128 -j RETURN
|
||||
#ip6tables -t mangle -A SS-MARK -d fc00::/7 -j RETURN
|
||||
#ip6tables -t mangle -A SS-MARK -d fe80::/10 -j RETURN
|
||||
|
||||
# Bypass sslocal with mask 0xff (255)
|
||||
iptables -t mangle -A SS-MASK -j RETURN -m mark --mark 0xff
|
||||
#ip6tables -t mangle -A SS-MASK -j RETURN -m mark --mark 0xff
|
||||
iptables -t mangle -A SS-MARK -j RETURN -m mark --mark 0xff
|
||||
#ip6tables -t mangle -A SS-MARK -j RETURN -m mark --mark 0xff
|
||||
|
||||
# Reroute
|
||||
iptables -t mangle -A SS-MASK -p udp -j MARK --set-mark 0x2333
|
||||
iptables -t mangle -A SS-MASK -p tcp -j MARK --set-mark 0x2333
|
||||
#ip6tables -t mangle -A SS-MASK -p udp -j MARK --set-mark 0x2333
|
||||
#ip6tables -t mangle -A SS-MASK -p tcp -j MARK --set-mark 0x2333
|
||||
iptables -t mangle -A SS-MARK -p udp -j MARK --set-mark 0x2333
|
||||
iptables -t mangle -A SS-MARK -p tcp -j MARK --set-mark 0x2333
|
||||
#ip6tables -t mangle -A SS-MARK -p udp -j MARK --set-mark 0x2333
|
||||
#ip6tables -t mangle -A SS-MARK -p tcp -j MARK --set-mark 0x2333
|
||||
|
||||
# Apply
|
||||
iptables -t mangle -A OUTPUT -j SS-MASK
|
||||
#ip6tables -t mangle -A OUTPUT -j SS-MASK
|
||||
iptables -t mangle -A OUTPUT -j SS-MARK
|
||||
#ip6tables -t mangle -A OUTPUT -j SS-MARK
|
||||
|
||||
@@ -67,6 +67,7 @@ pub struct DecryptedReader {
|
||||
cipher: Option<Cipher>,
|
||||
buffer: BytesMut,
|
||||
method: CipherKind,
|
||||
salt: Option<Bytes>,
|
||||
}
|
||||
|
||||
impl DecryptedReader {
|
||||
@@ -79,6 +80,7 @@ impl DecryptedReader {
|
||||
cipher: None,
|
||||
buffer: BytesMut::with_capacity(method.salt_len()),
|
||||
method,
|
||||
salt: None,
|
||||
}
|
||||
} else {
|
||||
DecryptedReader {
|
||||
@@ -86,6 +88,7 @@ impl DecryptedReader {
|
||||
cipher: Some(Cipher::new(method, key, &[])),
|
||||
buffer: BytesMut::with_capacity(2 + method.tag_len()),
|
||||
method,
|
||||
salt: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -105,7 +108,7 @@ impl DecryptedReader {
|
||||
match self.state {
|
||||
DecryptReadState::WaitSalt { ref key } => {
|
||||
let key = unsafe { &*(key.as_ref() as *const _) };
|
||||
ready!(self.poll_read_salt(cx, context, stream, key))?;
|
||||
ready!(self.poll_read_salt(cx, stream, key))?;
|
||||
|
||||
self.buffer.clear();
|
||||
self.state = DecryptReadState::ReadLength;
|
||||
@@ -122,7 +125,7 @@ impl DecryptedReader {
|
||||
}
|
||||
},
|
||||
DecryptReadState::ReadData { length } => {
|
||||
ready!(self.poll_read_data(cx, stream, length))?;
|
||||
ready!(self.poll_read_data(cx, context, stream, length))?;
|
||||
|
||||
self.state = DecryptReadState::BufferedData { pos: 0 };
|
||||
}
|
||||
@@ -146,13 +149,7 @@ impl DecryptedReader {
|
||||
}
|
||||
}
|
||||
|
||||
fn poll_read_salt<S>(
|
||||
&mut self,
|
||||
cx: &mut task::Context<'_>,
|
||||
context: &Context,
|
||||
stream: &mut S,
|
||||
key: &[u8],
|
||||
) -> Poll<io::Result<()>>
|
||||
fn poll_read_salt<S>(&mut self, cx: &mut task::Context<'_>, stream: &mut S, key: &[u8]) -> Poll<io::Result<()>>
|
||||
where
|
||||
S: AsyncRead + Unpin + ?Sized,
|
||||
{
|
||||
@@ -164,14 +161,10 @@ impl DecryptedReader {
|
||||
}
|
||||
|
||||
let salt = &self.buffer[..salt_len];
|
||||
if context.check_nonce_and_set(&salt) {
|
||||
use std::io::Error;
|
||||
|
||||
trace!("detected repeated AEAD salt {:?}", ByteStr::new(&salt));
|
||||
|
||||
let err = Error::new(ErrorKind::Other, "detected repeated salt");
|
||||
return Err(err).into();
|
||||
}
|
||||
// #442 Remember salt in filter after first successful decryption.
|
||||
//
|
||||
// If we check salt right here will allow attacker to flood our filter and eventually block all of our legitimate clients' requests.
|
||||
self.salt = Some(Bytes::copy_from_slice(salt));
|
||||
|
||||
trace!("got AEAD salt {:?}", ByteStr::new(salt));
|
||||
|
||||
@@ -201,7 +194,13 @@ impl DecryptedReader {
|
||||
Ok(Some(length)).into()
|
||||
}
|
||||
|
||||
fn poll_read_data<S>(&mut self, cx: &mut task::Context<'_>, stream: &mut S, size: usize) -> Poll<io::Result<()>>
|
||||
fn poll_read_data<S>(
|
||||
&mut self,
|
||||
cx: &mut task::Context<'_>,
|
||||
context: &Context,
|
||||
stream: &mut S,
|
||||
size: usize,
|
||||
) -> Poll<io::Result<()>>
|
||||
where
|
||||
S: AsyncRead + Unpin + ?Sized,
|
||||
{
|
||||
@@ -219,6 +218,20 @@ impl DecryptedReader {
|
||||
return Err(io::Error::new(ErrorKind::Other, "invalid tag-in")).into();
|
||||
}
|
||||
|
||||
// Check repeated salt after first successful decryption #442
|
||||
if self.salt.is_some() {
|
||||
let salt = self.salt.take().unwrap();
|
||||
|
||||
if context.check_nonce_and_set(&salt) {
|
||||
use std::io::Error;
|
||||
|
||||
trace!("detected repeated AEAD salt {:?}", ByteStr::new(&salt));
|
||||
|
||||
let err = Error::new(ErrorKind::Other, "detected repeated salt");
|
||||
return Err(err).into();
|
||||
}
|
||||
}
|
||||
|
||||
// Remote TAG
|
||||
self.buffer.truncate(size);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user