I have two network interfaces on my Ubuntu server, eth0 and eth1. Currently both are configured with the standard routing rules, but I want to configure eth1 so it can only access other computers on the local network and NOT the Internet. Eth0 should be able to access everything. I've seen similar questions where people want to accomplish the opposite (access the Internet but not local computers), but am unsure how to adjust the rules to accomplish what I desire.
What rule(s) would I add to lock out eth1 from accessing (and be accessed by) the Web, but still allow LAN access?
Edit: A bit more information.
Current Scheme. Here's a paint image of what I currently have set up. There is a separate router on the network that handles connections to the internet.
I want to be able to disconnect the server from the internet at the drop of a hat if I suspect an attack (such as someone swiping my private keys and I need time to "change the locks"), but still be able to access the server via SSH from another local machine to fix the problems. I either want to accomplish this by disconnecting the red wire or running a script to bring down the eth0 interface.
Is there a way to accomplish this scenario with both interfaces connected to the switch, or do I need to move the red wire and connect eth0 directly to the router? I suspect by the answer below the ideal scenario would be to let eth0 handle all the internet activity and let eth1 handle the local activity.
Answer
I'm still a bit confused by your description. Here is what I understood:
+--------------+ +---------+
| Ubuntu eth0 |----| Router/ |---- Internet
| | | Modem |
| | +---------|
| |
| | +---------+
| eth1 |----| Switch |---- LAN PC 1
| | | |
| | | |---- LAN PC 2
+--------------+ +---------+
So LAN PC 1, LAN PC 2 and the Ubuntu Server should be able to talk to each other (via eth1 on the Ubuntu server), and the Ubuntu server should be able to access the Internet, but neither LAN PC 1 nor LAN PC 2 should be able to access the Internet.
In that case, you just have to disable forwarding on the Ubuntu server (echo 0 > /proc/sys/net/ipv4/ip_forward
, though it's disabled by default, or edit /etc/sysctl.conf
to do that on boot). The server will contact the Internet via eth0, and the LAN via eth1.
If the situation is different, please edit your question to describe the situation.
Note that it's not network interfaces (eth0, eth1) that "access" anything, it's the computers themselves. Maybe that is the reason of the communication problem.
Edit
Yes, you can accomplish your scenario according to your drawing, but it will be tricky: "Double" connections to a network are no fun.
There's a solution that's a lot simpler, of it's ok that the other local PCs loose internet connection during an attack: Connect all PCs to the switch, and remove cable from switch to router when you suspect something. All computers keep their IP addresses, you can ssh
from a local PC into the server using the numeric address. (Or you can run DNS/DHCP from the server instead of the modem/router in the first place.)
The proper solution to protect your server and at the same time allow your local PCs to continue using the internet is to set up a firewall (a cheap embedded computer with at least two LAN interfaces will do) between the modem/router and the Ubuntu server in the DMZ on the one side, and the local PCs on the other side. If you have full access to your modem/router (e.g. with OpenWRT), this firewall can also be placed there.
Now for your plan: It doesn't matter if the Ubuntu server is connected directly to the router or to the switch: The router has an internal switch, and cascaded switches don't change things, they count all as part of the same LAN segment.
Here's an outline what you need to do. It's untested, and will need a bit of fiddling, and there may be gotchas which prevent it from working at all.
Assuming the Router/Modem runs a DHCP server, make sure both eth0 and eth1 get different IP addresses. Also make sure eth1 doesn't get the default route. You may have to modify
dhclient.conf
for that, possibly write differentrequest
lines for both inrefaces.Routing: eth0 should get the default route. eth1 should never get a default route, even when eth0 is down. You may have to fight installed programs/scripts to achieve this. eth1 should either only get a link-local route with higher metric (if that is possible), or no route at all (or a /1 subnet) while eth0 is up, and a link-local one when eth0 is down. That means you may have to set routes for eth1 in
/etc/network/if-{up,down}
for eth0 (or whatever the systemd equivalent is these day, if it works in systemd at all...).
Reason: if both eth0 and eth1 have routes with same metric into the local LAN, packets will be randomly sent from both interfaces, with different source IP addresses. To the receiving end in the LAN it will look like about half the packets are dropped (because the ones with the right source address never arrive). This is why a "double interface" into the same segment is no fun.
- You need
iptables
rules that block anything on eth1 except the port for ssh to and from the local LAN. Google for tutorials.
Quite a bit of work.
Edit
A simpler alternative is to create a network namespace (google for tutorials), move eth1 into that namespace, run sshd
inside it, and all the other services outside of the namespace. That means both interfaces can have default routes etc., only sshd goes via eth1, and all other services go via eth0. eth1 would need iptables
rule to restrict it to the local LAN on INPUT
and OUTPUT
.
Edit
As I said, remote debugging is very difficult (no feedback). If you can't get it to work, please make a new question and describe exactly what you did (ip route
, ip addr
on all relevant machines, tcpdump
on relevant interfaces when you do ssh
, etc.).
I just checked; as I don't have two ethernet interfaces, I used a virtual eth pair. Roughly, create a namespace and move your eth1
into it
# ip netns add blue
# ip link set eth1 netns blue
Make sure it gets a valid address and route, either by enabling DHCP and making sure it gets run, whatever method your system uses, or by setting it manually (for testing), something like
# ip netns exec blue ip link set eth1 down
# ip netns exec blue ip addr add 192.168.4.1/24 dev eth1
# ip netns exec blue ip link set eth1 up
You should get an address and a route, e.g. (this was done with a virtual eth pair, so it won't look exactly like this):
# ip ip netns exec blue ip addr
1: lo: mtu 65536 qdisc noop state DOWN group default qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth1: mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether e6:5a:19:e0:63:75 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 192.168.44.1/24 scope global veth1b
valid_lft forever preferred_lft forever
inet6 fe80::e45a:19ff:fee0:6375/64 scope link
valid_lft forever preferred_lft forever
# ip netns exec blue ip route
192.168.44.0/24 dev eth1 proto kernel scope link src 192.168.44.1
Run sshd
in that namespace in another xterm, add debugging flags and use a different port to make sure there's no confusion:
# ip netns exec blue /usr/sbin/sshd -D -d -p 222
Connect to it from the outside with ssh 192.168.44.1 -p 222
, and that worked fine here: you can see the connection process in the debug messages.
No comments:
Post a Comment