6

What is the most elegant way to use only the Raspberry Pi in the local network?

For now I blocked all outgoing ports on my router, but I don't think this is the best way to do it.

I am running NOOBS' Raspbian OS.

1
  • 1
    Removing the default gateway will mean it knows how to talk to computers on the local network but not from the outside. The simplest is probably an ordinary router for home use, with uPnP turned off! Mar 12, 2014 at 7:07

4 Answers 4

10

I think that a easy way to achieve this is using the ufw (Uncomplicated Firewall), a minimalist command line tool. Actually this tool uses iptables but more friendly way. It should be installed on your system, but if not you can install it typing:

sudo apt-get install ufw

First, deny all incoming connetions to your raspberry pi:

sudo ufw default deny

Second, only allow the local network connections ( In this example I suppose that your local network is 192.168.0.0/24)

sudo ufw allow from 192.168.0.0/24

Finally, enable the ufw typing:

sudo ufw enable

You can see the active rules typing:

sudo ufw status verbose

You can learn more about UFW tool in the ubuntu documentation (https://help.ubuntu.com/community/UFW)

0
5

If you don't want ANY form of communication to the outside world, see goldilocks's answer. But if you still want to allow outgoing connections (e.g. browsing, apt-get, etc...), read on.

Your router firewall is a good setup in most cases. If you want some extra protection, you may wish to enable the Pi's own firewall. This answer applies to all linux systems, that includes your Raspberry Pi. A Linux OS has a built-in firewall called iptables. We will need to tell iptables to block all connections, except for connections originating from LAN.

You need to know what your LAN IP address range is. This is achieved by writing ifconfig in a terminal. The output varies depending on your setup, your line of interest is the inet addr. In my case it's inet addr:10.0.0.2. Your LAN IP address range is the first 3 numbers of your IP address, that is, 10.0.0.* in my case.

Now we know what we need to do: Block all incoming traffic unless it is originating from LAN. That is, unless it's in the range 10.0.0.0 - 10.0.0.255. Let's translate that into iptables commands:

iptables -P INPUT DROP  #Block all incoming packets unless they are excluded below
iptables -P FORWARD DROP 
iptables -P OUTPUT ACCEPT #Allow outgoing packets
sudo iptables -A INPUT -m iprange --src-range 10.0.0.0-10.0.0.255 -j ACCEPT #Allow incoming packets if they are from LAN
sudo iptables -A INPUT -i lo -j ACCEPT # Allow localhost
sudo iptables -A OUTPUT -o lo -j ACCEPT # Allow localhost
sudo iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT #Allow incoming packets if they are part of an established connection. (Allow responses to outgoing traffic such as apt-get, browsing, time sync, etc.)

Note that this still allows the RPi to talk to the outside world if the PI itself initiated the connection. This would allow apt-get, browsing, and time syncing to function (The Pi needs the Internet to tell time)

make sure you specified your own range in case it isn't 10.0.0.*.

That should work. But iptables forgets all commands upon reboot. Therefore, you should append the commands to a start up script. I personally do it by adding the commands above to /etc/rc.local using sudo nano /etc/rc.local

14
  • +1 However, you have not blocked outgoing traffic (see my answer). Worth noting that -A means append and -P means prepend.
    – goldilocks
    Mar 12, 2014 at 2:57
  • Why is blocking outgoing traffic important? I think it's very limiting and offers no advantage. Mar 12, 2014 at 4:07
  • If input is blocked, leaving output open is useless for any normal purpose anyway (unless you predicate everything with a rule to accept related/established connections -- but then that is not limiting the pi to the local network!). If this is just to prevent your kids from accessing the internet, blocking one or the other will do that. However, if the concern is security, any malware which makes its way onto a device where output is open will have a chance to get a scrap of information out (basically, "I'm running here"), which is the first thing malware will try and do...
    – goldilocks
    Mar 12, 2014 at 4:20
  • In case that first sentence is not clear: communication is two way. There is no point ("for any normal purpose") in preventing it only one way. So saying that "it is very limiting" to then also block output makes no sense -- you cannot have any effective communication with anything if you cannot receive a reply. That holds true for malware too, except that it will be able to indicate to a remote server that it is at running by the fact of the transmission, and the transmission will include the router's external IP and the device's MAC address in the IP header.
    – goldilocks
    Mar 12, 2014 at 4:25
  • Thank you! I missed that. I added a rule to allow outgoing connections to work properly, a peer review of whether this is the correct way to do it would be great. Mar 12, 2014 at 4:29
4

The most straightforward way would be to use the pi's own firewall (on raspbian, iptables) to block traffic to or from any address that is not part of the LAN.

Iptables rules are assessed in order, so if you set these two first:

-A INPUT ! -s 192.168.0.0/24 -j REJECT --reject-with icmp-net-prohibited
-A OUTPUT ! -d 192.168.0.0/24 -j REJECT --reject-with icmp-net-prohibited

Then everything from outside your local subnet will be rejected, presuming this is an appropriate CIDR. If all your local addresses are prefixed 192.168.0 then it is; some routers use 192.168.1, etc. Since the 192.168 prefix is reserved for private networks in any case, you are safe using 192.168.0.0/16, which covers all those possibilities (see also Hello World's answer WRT determining the private network prefix from ifconfig output; it can also begin 10.0 or 172.16).

By way of quick explanation, the ! inverts the match. This is very important, otherwise what you are doing is rejecting everything local (and by implication allowing everything else).

Raspbian by default does not activate the firewall but it is installed. A complete explanation of how it works is beyond the scope of this answer, but a very simple configuration using the aforementioned rules might look like this:

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]

# The first two rules allow the system to communicate internally.
-A INPUT -i lo -j ACCEPT
-A OUTPUT -d 127.0.0.1 -j ACCEPT
# Now reject stuff from outside the LAN.
-A INPUT ! -s 192.168.0.0/16 -j REJECT --reject-with icmp-net-prohibited
-A OUTPUT ! -d 192.168.0.0/16 -j REJECT --reject-with icmp-net-prohibited
# Finally, accept everything which does not match a previous rule.
-A INPUT -j ACCEPT
-A OUTPUT -j ACCEPT
-A FORWARD -j ACCEPT

Save that as a text file owned by root with permissions 644 (or 600). It does not matter what you call it or where you put it, but for illustration I'll use /etc/iptables.rules. To apply, run iptables-restore < /etc/iptables.rules. There should not be any output; if there is you typed something wrong and this will be indicated. To load these at boot, add the following line to /etc/rc.local:

/sbin/iptables-restore < /etc/iptables.rules

It's important to use the full path of executables in rc.local (e.g. /sbin/iptables-restore, not just iptables-restore) since $PATH may not be set.

CAVEAT

You won't be able to run apt-get, etc., this way. However, you can disable all the rules with iptables -F, do whatever, and then reinstate them with the iptables-restore < /etc/iptables.rules bit again.

Also, this presumes everything on your LAN is reasonably trustworthy. That's probably fine, since while what a firewall does is prevent a connection from occurring, allowing a connection to occur doesn't mean much -- e.g., it doesn't mean some malware on your iphone can now easily log in as root on the pi via ssh. It just means it won't be prevented from making a request to do so (which ssh itself will block).

1

Not 100% sure what is the most elegant way to only use a raspberry pi on your network. I personally have an Class C network on the 192.168.0.x range. I also gave my Raspberry Pi a static IP address. My router is locked down with all ports closed and uPnP disabled and running tests on the LAN/WAN evidently show this. I also run SPI on my Router/Firewall, Stateful Packet Inspection.

My advice would be to manually assign a static IP address, this will make life easier when you SSH and VNC into your Raspberry Pi, to do this just do the following.

1.) Turn on your Raspberry Pi (Raspbian)

2.) Login but don't start up your desktop environment.

3.) From the shell we need to view the interfaces so type this: cat /etc/network/interfaces

4.) At the line iface eth0 inet dhcp shows our interface uses DHCP to obtain an IP address.

5.) Now we need to grab some info from our router and Pi so lets run commands ifconfig

6.) Look for

eth0      Link encap:Ethernet  HWaddr b8:27:eb:b3:fc:2c
               inet addr:192.168.0.10  Bcast:192.168.0.255  Mask:255.255.255.0

7.) Write down the following and take note of it

inet addr – 192.168.0.10 (Pi's Current IP Address)
Bcast –  192.168.0.255 (The Broadcast IP Range)
Mask –  255.255.255.0 (Subnet Mask Address)

8.) We need more info from the router so lets run command from the shell "netstat -nr" you can also use command "route -n" it will also display the same info. The part we are looking for is this

'Gateway' Address – 192.168.0.254
'Destination' Address – 192.168.0.0

9.) We now need to input this info into our Raspberry Pi so lets run command sudo pico /etc/network/interfaces You can use another editor such as nano or vi. I personally prefer Pico among others.

10.) Now lets change the following line iface eth0 inet dhcp and change this to iface eth0 inet static.

11.) Also we need to include the following adjusted accordingly, choose YOUR OWN IP, I selected ".20" as my chosen static IP address

address 192.168.0.20
netmask 255.255.255.0
network 192.168.0.0
broadcast 192.168.0.255
gateway 192.168.0.254

12.) Save the file (with nano you press Ctrl+O) and update changes to the interface configuration the file you just edited.

13.) Now we can either reboot or be crafty by stopping and restarting the interface service, now lets run command sudo /etc/init.d/networking stop and then sudo /etc/init.d/networking start this will stop and start the service for the interface.

14.) now lets run a ping from the command prompt to your Pi, lets do this now ping 192.168.0.20

15.) Next we could run IPTABLES but that's going out of my depth, I'm sure someone else could shed some light into that.

Good luck, if I missed anything let me know, I hope this helps.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.