You want to prevent remote hosts from pretending to be local to your network.
For a single machine, to prevent remote hosts from pretending to be that machine, use the following:
# iptables -A INPUT -i external_interface -s your_IP_address -j REJECT
# ipchains -A input -i external_interface -s your_IP_address -j REJECT
If you have a Linux machine acting as a firewall for your internal network (say, 192.168.0.*) with two network interfaces, one internal and one external, and you want to prevent remote machines from spoofing internal IP addresses to the external interface, use the following:
# iptables -A INPUT -i external_interface -s 192.168.0.0/24 -j REJECT
Drop Versus Reject
The Linux firewall can refuse packets in two manners. iptables calls them DROP and REJECT, while ipchains uses the terminology DENY and REJECT. DROP (or DENY) simply swallows the packet, never to be seen again, and emits no response. REJECT, in contrast, responds to the packet with a friendly message back to the sender, something like "Hello, I have rejected your packet."
DROP and REJECT have pros and cons. In general, REJECT is more compliant with standards: hosts are supposed to send rejection notices. Used within your network, rejects make things easier to debug if problems occur. DROP gives a bit more security, but it's hard to say how much, and it increases the risk of other network-related problems for you. A DROP policy makes it appear to peers that your host is turned off or temporarily unreachable due to network problems. Attempts to connect to TCP services will take a long time to fail, as clients will receive no explicit rejection (TCP "reset" message), and will keep trying to connect. This may have unexpected consequences beyond the blocking the service. For example, some services automatically attempt to use the IDENT protocol (RFC 1413) to identify their clients. If you DROP incoming IDENT connections, some of your outgoing protocol sessions may be mysteriously slow to start up, as the remote server times out attempting to identify you.
On the other hand, REJECT can leave you open to denial of service attacks, with you as the unwitting patsy. Suppose a Hostile Third Party sends you packets with a forged source address from a victim site, V. In response, you reject the packets, returning them not to the Hostile Third Party, but to victim V, owner of the source address. Voilà?you are unintentionally flooding V with rejections. If you're a large site with hundreds or thousands of hosts, you might choose DROP to prevent them from being abused in such a manner. But if you're a home user, you're probably less likely to be targeted for this sort of attack, and perhaps REJECT is fine. To further complicate matters, the Linux kernel has features like ICMP rate-limiting that mitigate some of these concerns. We'll avoid religious arguments and simply say, "Choose the solution best for your situation."
In this chapter, we stick with REJECT for simplicity, but you may feel free to tailor the recipes more to your liking with DROP or DENY. Also note that iptables supports a variety of rejection messages: "Hello, my port is unreachable," "Bummer, that network is not accessible," "Sorry I'm not here right now, but leave a message at the beep," and so forth. (OK, we're kidding about one of those.) See the ?reject-with option.
# ipchains -A input -i external_interface -s 192.168.0.0/24 -j REJECT
For a single machine, simply enable source address verification in the kernel. [Recipe 2.1]