TCP push packet not delivered from tun - tcp

I setup simple packet intercept program, using two tuns, setup like this:
# ip tuntap add mode tun name tun0
# ip link set tun0 up
# ip addr add 10.0.0.0/31 dev tun0
# ip tuntap add mode tun name tun1
# ip link set tun1 up
# ip addr add 10.0.1.0/31 dev tun1
and redirect output to the program like this:
# ip rule add fwmark 1 table 1
# ip route add default dev tun0 table 1
# iptables -t mangle -A OUTPUT --source 192.168.1.0 -o enp34s0 -p tcp --dport 9732 -j MARK --set-mark 1
# iptables -t nat -A POSTROUTING --source 10.0.1.1 -o enp34s0 -j MASQUERADE
I enabled ip_forward and disabled rp_filter. Packets received on tun0 are processed, modified and ip/tcp checksums are updated.
I can even correctly intercept tcp handshake SYN -> ACK,SYN -> ACK part of communication, but after that, any incoming packet would be correctly intercepted modified and send out of tun, but it would never be delivered to local application.

Ok, found a problem, whilst I did recalculate the checksum, it only calculated correct one only for the TCP packets without any payload, thus TCP handshak get through and nothing else.

Related

How to send packets from a used port on Linux

I'm developing a Wireguard-based P2P VPN program.
I'd like to send packets from a port used by another process.
iptables SNAT and MASQUERADE didn't work.
The port :13613 is used by another process.
iptables -A POSTROUTING -p udp -m udp --sport 13614 -j SNAT --to-source :13613
I sent a packet from :13614, but got an error like
[::]:13614->XXX.XXX.XXX.XXX:44614: sendto: operation not permitted
How can I send packets from :13613.

OpenVPN - How do you NAT a client to another client's network

I have a openVPN server setup on a AWS instance and I would like to use it to route traffic from my home client (client1, 192.168.0.0/24) to a client(client2, 10.81.0.0/16) on a machine on a second network through the openVPN server. I want to route the connections from client1 to client2's network so that I can connect to several devices in client2's network. However I dont have control over the gateway in client2's network so I can't add a route back to the vpn.
As far as I can tell I have the openVPN configuration setup in that once client1 and client2 are connected I can access client2 from client1, the routes are also setup so that if I ping a machine on client2's network the traffic is routed through the vpn but no response happens as client2's network devices do not know how to route the vpn ips back to client2.
I am assuming that I need to setup nat masqurading at client2 but I am unsure how to properly handle this as I am not that familiar with iptables.
tried on client2:
iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE
server.conf
port 1194
proto udp
dev tun
user nobody
group nogroup
persist-key
persist-tun
keepalive 10 120
topology subnet
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
client-to-client
route 10.81.0.0 255.255.0.0
push "route 10.81.0.0 255.255.0.0"
dh none
ecdh-curve prime256v1
... encryption info ...
client-config-dir /etc/openvpn/ccd
status /var/log/openvpn/status.log
verb 3
ccd/client2
iroute 10.81.0.0 255.255.0.0
For anyone with a similar issue, I found this https://arashmilani.com/post?id=53 that helped me solve the issue.
For me I needed to add the following instead of what I tried.
iptables -A FORWARD -i tun0 -j ACCEPT
iptables -A FORWARD -i tun0 -o eno2 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i eno2 -o tun+ -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eno2 -j MASQUERADE
tun0 is the tunnel interface from the VPN and eno2 is the interface for client2's network. 10.8.0.0/24 is the default subnet for the VPN subnet.
The forwarding was the big issue, also the masquerade is based on the ip address range of the VPN on the output interface.

Using Squid and/or iptables to share ip address over a bridge

Edited for additional clarity and added links to other attempted solutions.
I have been attempting this for several days now with one other developer, and we are getting nowhere and there are a number of comments on-line about how there are no examples to do this sort of thing (including someone who wrote some c code to do something similar though not exactly this). We have attempted to implement the solution described on SuperUser as well, but so far it does not seem like the local http server receives any of the requests as expected.
What we are trying to do:
On a device (test device) that sits between another device (mini computer) and the network. We want the test device to use the ip address of the mini computer to communicate with the control server -- in other words, we don't want it to have to have its own IP address but use that of the minicomputer for control commands (e.g., block network traffic, resume network traffic). Things are set up like so:
Mini Computer| | Test Device | | LAN
Ethernet |<-->|eth_minicomp<-->br0<-->eth_network|<-->| Ethernet
So for traffic that is:
coming from the control IP address, AND
destined for the mini computer IP address
We want the test device to intercept (and NOT forward), but use locally.
Whereas for traffic that is:
comping from the test device, AND
destined for the control IP address
We want it going out the eth_network interface with the src address being the mini computer ip address.
Latest Attempt
I have a device set up as a transparent bridge which works:
# Bring interfaces down
ip link set dev eth_minicomp down
ip link set dev eth_network down
# Create bridge
ip link add name br0 type bridge
ip link set dev br0 up
# Remove IP addresses from interfaces
ip address flush dev eth_minicomp
ip address add 0.0.0.0 dev eth_minicomp
ip address flush dev eth_network
ip address add 0.0.0.0 dev eth_network
# Bring interfaces back up
ip link set dev eth_minicomp up
ip link set dev eth_network up
# Set promisc (not sure about on br0, but should not have an effect)
ip link set dev eth_minicomp promisc on
ip link set dev eth_network promisc on
ip link set dev br0 promisc on
# Add interfaces to bridge
ip link set dev eth_minicomp master br0
ip link set dev eth_network master br0
I had been hoping to use iptables/tproxy or perhaps Squid to handle this by routing the desired TCP/IP traffice to lo (127.0.0.1), but cannot seem to get this to work. My latest attempt was trying to use
sysctl net.ipv4.ip_forward=1
sysctl net.ipv4.conf.lo.rp_filter=1
iptables -t mangle -F
iptables -t mangle -X
iptables -t mangle -N DIVERT
iptables -t mangle -A DIVERT -j MARK --set-mark 0x01/0x01
iptables -t mangle -A DIVERT -j ACCEPT
iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT
iptables -t mangle -A PREROUTING -s $CONTROLLER_IP -p tcp -j TPROXY \
--tproxy-mark 0x1/0x1 --on-port 80
ip route flush table 100
ip rule add fwmark 1 lookup 100
ip route add local 0.0.0.0/0 dev lo table 100
TPROXY seem to require at least the net.ipv4.ip_forward set 1,2, however, following the procedure on the Squid TPROXY Feature page does not seem to be set up for this type of solution.
And various permutations on -s, -d, --on-port, etc. It seems that I could use the Suid man in the middle setup to do something like this, but I do not see how. Trying to search for Suid man in the middle or Squid localhost proxy on SO returns a lot of not-quite-what-i'm-looking-for questions.
So how do we route these packets to a local server on the test device for handling? RTFM responses are more than welcome, we just cant find the fabulous manual.
Got it working with help from a team member using ebtables and iptables.
The biggest surprise in getting this working was finding out that if you use ebtables to create an Ethernet bridge, you have to DROP the Ethernet frames in order for them to get kicked up to the network layer. We all thought that DROP actually dropped the Ethernet frame and therefore the TCP/IP packets. Go figure.
We now have a device that can share the MAC and IP address of the computer to which it is attached and still communicate without disrupting the computer.
INT_IP=169.254.1.1
SRC_IP=192.168.1.2
DST_IP=192.168.1.3
EXT_PORT=80
INT_PORT=54321
# Bring interfaces to bridge down
ip link set dev eth1 down
ip link set dev eth2 down
# Remove any ip addresses on the interfaces
ip address flush dev eth1
ip address flush dev eth2
ip address add 0.0.0.0 dev eth1
ip address add 0.0.0.0 dev eth2
# Bring interfaces back up
ip link set dev eth1 up
ip link set dev eth2 up
# Set promiscuous on the interfaces
ip link set dev eth1 promisc on
ip link set dev eth2 promisc on
# Create bridge
ip link add name br0 type bridge
ip link set dev br0 up
# Add interfaces to bridge
ip link set dev eth1 master br0
ip link set dev eth2 master br0
# Add a local private IP to the bridge
ip address add $INT_IP dev "br0"
# Allow forwarding
sysctl -w net.ipv4.ip_forward=1
# Set up ethernet bridge with ebtables.
# NOTE the drop. Completely counterintuitive.
ebtables -t broute -A BROUTING -p IPv4 --ip-source $SRC_IP \
--ip-destination $DST_IP --ip-proto tcp --ip-dport \
$EXT_PORT -j redirect --redirect-target DROP
ebtables -t broute -A BROUTING -p IPv4 --ip-proto tcp \
--ip-sport $INT_PORT -j redirect --redirect-target \
DROP
# Set up iptables to handle diverting requests that originate
# from $SRC_IP destined for $DST_IP on port $EXT_PORT and send
# them to $INT_IP and $EXT_PORT in stead where you can have a
# service / thingy to handle them.
iptables -t nat -A PREROUTING -p tcp -s $SRC_IP -d $DST_IP \
--dport $EXT_PORT -j DNAT \
--to-destination $INT_IP:$INT_PORT
iptables -t nat -A POSTROUTING -p tcp -d $INT_IP \
--dport $EXT_PORT -j SNAT --to-source \
$DST_IP:$EXT_PORT
iptables -t nat -A POSTROUTING -j MASQUERADE
Now if you try to reach $DST_IP on port $EXT_PORT from $SRC_IP, it will be routed to $INT_IP on $INT_PORT in stead. Conversely, if you try to send data to $INT_IP on $INT_PORT from the system on which you configured this, all traffic will go to $SRC_IP on $EXT_PORT
-2 karma! Woohoo!

IPTable rules to restrict eth1 access to ports 80 and 443

I have a service listening to customer traffic on ports 80 and 443 of eth1. The servers hosting my service also host other admin/privileged access content on eth0 and localhost
I am trying to setup iptable rules to lock down eth1 on servers which is on same network as clients (block things like ssh through eth1/ accessing internal services running on port 9904 etc.) I also want to make sure that the rules dont forbid regular access to eth1:80 and eth1:443. I have come up with below rules but wanted to review with iptable gurus on possible issues with this rule.
-A INPUT -i eth1 -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -i eth1 -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -i eth1 -j DROP
Do the rules above suffice
How does above differ from the rules found when googling
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-A INPUT -i eth1 -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -i eth1 -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -i eth1 -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j DROP
-A INPUT -i eth1 -p tcp -j ACCEPT
-A INPUT -i eth1 -j DROP
thanks i got this answered in https://serverfault.com/questions/834534/iptable-rules-to-restrict-eth1-access-to-ports-80-and-443 , adding it here for completeness
The first set of rules first allow all incoming packets on your ports
80 and 443. Then it drops ALL other incoming packets (except those
already accepted).
The second set of rules first allow all incoming packets on ports 80
and 443. Then it drops incoming connections (excluding 80 and 443 that
are already accepted), which are packets with only the SYN flag set.
Then it allows all incoming packets.
The difference here is what happens to your OUTGOING connections. In
the first ruleset, if you attempt to connect to another server, any
packets that server sends in response will be dropped so you will
never receive any data. In the second case, those packets will be
allowed since the first packet from the remote server will have both
SYN and ACK set and therefore pass the SYN test, and any following
packets will not have SYN set at all, and therefore pass the test.
This has been traditionally done using conntrack which requires the
kernel to keep track of every connection in the firewall, with a
command like
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
that matches the incoming packet either to an existing connection, or
a connection related to some other existing connection (eg FTP data
connections). If you aren't using FTP or other protocols that use
multiple random ports, then the second ruleset achieves basically the
same result without the overhead of tracking and inspecting these
connections.

How to forward packet from eth0 to a tun/tap device?

Here is the topo: HostA(eth0) ---- (eth0)HostB
I have created a tun/tap device on HostB, for say tun0 or tap0. When eth0 of HostB receives a packet from HostA, maybe a ICMPv6(NS, echo request, etc.) or a UDP/TCP packet(encapsulated with IPv6 header), I want to forward this packet from eth0 to tap0. After doing something to this packet, I also want to send a reply back to HostA, through tap0 and eth0.
I cannot find a way to do that, can some one help me or give some hints?
This is an extremely basic routing question, probably unsuitable for Stack Overflow.
You need something like this on Host B:
HostB# sysctl -w net.ipv6.conf.all.forwarding=1
HostB# ip -6 addr add 2001:db8:0:0::1/64 dev eth0
HostB# ip -6 addr add 2001:db8:0:1::1/64 dev tun0
Then on Host A:
HostA# ip -6 addr add 2001:db8:0:0::2/64 dev eth0
HostA# ip -6 route add default via 2001:db8:0:0::1 dev eth0
HostA# ping6 2001:db8:0:1::2 # <-- should work if that host exists on tun0

Resources