Difference between revisions of "Raspberry Pi IPv6 firewall tester installation"

From timswiki
Jump to navigation Jump to search
 
(7 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
How to make your own Raspberry Pi IPv6 firewall tester.
 
How to make your own Raspberry Pi IPv6 firewall tester.
 
<analytics uacct="UA-27654202-1" ></analytics>
 
  
 
=== Suggested Reading ===
 
=== Suggested Reading ===
Line 23: Line 21:
 
Then add a user, using a non-obvious username, e.g. '''PlnUsr456''' : (follow the prompts)
 
Then add a user, using a non-obvious username, e.g. '''PlnUsr456''' : (follow the prompts)
 
    
 
    
   # adduser
+
   # useradd -m PlnUser456
 +
  # passwd PlnUser456
  
  
Line 51: Line 50:
 
=== Simplistic IPv6 Firewall ===
 
=== Simplistic IPv6 Firewall ===
  
By default IPv6 support is disabled in later Arch Linux releases. To enable it, edit /boot/cmdline.txt and remove the ipv6.disable=1 statement from the beginning of the line.
+
By default IPv6 support is disabled in later Arch Linux releases. To enable it, edit '''/boot/cmdline.txt''' and remove the '''ipv6.disable=1''' statement from the beginning of the line.
 +
 
 +
Following this modification it is sensible to reboot your Raspberry Pi and check that it has been correctly allocated an IPv6 address, using ifconfig:
  
 +
  # ifconfig eth0
 +
  eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
 +
        inet AA.BB.C.DD  netmask 255.255.255.0  broadcast AA.BB.C.255
 +
        inet6 '''2001:470:971f:3:ba27:ebff:fecc:dc7c'''  prefixlen 64  scopeid 0x0<global>
 +
        inet6 fe80::ba27:ebff:fecc:dc7c  prefixlen 64  scopeid 0x20<link>
 +
        ether b8:27:eb:cc:dc:7c  txqueuelen 1000  (Ethernet)
 +
        RX packets 721789  bytes 103366589 (98.5 MiB)
 +
        RX errors 0  dropped 48  overruns 0  frame 0
 +
        TX packets 231210  bytes 130480722 (124.4 MiB)
 +
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
  
 
As a general starting point please read the [https://wiki.archlinux.org/index.php/Iptables ArchLinux IPtables documentation].  
 
As a general starting point please read the [https://wiki.archlinux.org/index.php/Iptables ArchLinux IPtables documentation].  
Line 190: Line 201:
 
Once you're satisfied that the IPv6 firewall rules are performing correctly then they can be saved using the following command:
 
Once you're satisfied that the IPv6 firewall rules are performing correctly then they can be saved using the following command:
  
   # rc.d save ip6tables
+
   # ip6tables-save >/etc/iptables/ip6tables.rules
  
 
Note that if you're also using IPv4 then don't forget to setup a similar IPv4 firewall ruleset. Again this example is only suitable for use in a trusted environment and needs further consideration for an internet facing machine.
 
Note that if you're also using IPv4 then don't forget to setup a similar IPv4 firewall ruleset. Again this example is only suitable for use in a trusted environment and needs further consideration for an internet facing machine.
Line 223: Line 234:
 
Once you're happy with your IPv4 firewall then you can save the active rules using the following command:
 
Once you're happy with your IPv4 firewall then you can save the active rules using the following command:
  
   # rc.d save iptables
+
   # iptables-save >/etc/iptables/iptables.rules
  
Note that it is import to check full functionality still exists with your firewall in place - this particularly applies to address allocation (e.g. DHCP and SLAAC) procedures which may mean that a misconfigured firewall makes your Raspberry Pi unreachable. This is one reason why it is useful to develop the two rulesets (IPv4 and IPv6) separately, since if you misconfigure one firewall and lose connectivity then you can fall back to the working protocol version to correct your mistake. Once you're happy that both firewall sets are correct then you can insert ''both'' sets into '''/etc/rc.conf''' DAEMONS statement before the network module is called:
+
Note that it is import to check full functionality still exists with your firewall in place - this particularly applies to address allocation (e.g. DHCP and SLAAC) procedures which may mean that a misconfigured firewall makes your Raspberry Pi unreachable. This is one reason why it is useful to develop the two rulesets (IPv4 and IPv6) separately, since if you misconfigure one firewall and lose connectivity then you can fall back to the working protocol version to correct your mistake. Once you're happy that both firewall sets are correct then you can enable the services from boot:
  
   DAEMONS=(!hwclock syslog-ng '''iptables''' '''ip6tables''' network openntpd @netfs @crond @sshd @mysqld @httpd)
+
   # systemctl enable ip6tables
 +
  # systemctl enable iptables
  
 
You can check for dropped/logged packets (in the examples above logging is included for the IPv6 packet filter) using the following command:
 
You can check for dropped/logged packets (in the examples above logging is included for the IPv6 packet filter) using the following command:
Line 239: Line 251:
 
    
 
    
 
   # pacman -S apache php php-apache mysql
 
   # pacman -S apache php php-apache mysql
 +
 +
Note: if you are running on a Model B version 1 then edit /etc/mysql/my.cnf to specify '''innodb_buffer_pool_size = 16M''' before attempting to start the service.
 
      
 
      
   # rc.d start mysqld  
+
   # systemctl start mysqld  
 
    
 
    
 
Don't forget to add a MySQL password:
 
Don't forget to add a MySQL password:
Line 248: Line 262:
 
    
 
    
  
Then Edit /etc/rc.conf (to start MySQL at boot):  
+
Then issue the following command to start MySQL at boot:  
 
    
 
    
   DAEMONS=(... mysqld ...)
+
   # systemctl enable mysqld
 
    
 
    
  
Line 257: Line 271:
 
   /srv/http/
 
   /srv/http/
 
             htdocs/ - DocumentRoot directory for storage of your served web pages (e.g. index.php discussed below)
 
             htdocs/ - DocumentRoot directory for storage of your served web pages (e.g. index.php discussed below)
             cgi-bin6/ - directory for the ipscan cgi executables
+
             cgi-bin6/ - directory for the IPscan cgi executables
 
    
 
    
 
If you follow this suggestion then don't forget to modify the DocumentRoot setting in the apache configuration file! Having followed the php installation guide then you'll also need to update php's base directory to match Apache inside '''/etc/php/php.ini''':
 
If you follow this suggestion then don't forget to modify the DocumentRoot setting in the apache configuration file! Having followed the php installation guide then you'll also need to update php's base directory to match Apache inside '''/etc/php/php.ini''':
Line 274: Line 288:
 
Once Apache and PHP start successfully:
 
Once Apache and PHP start successfully:
  
   # rc.d start httpd
+
   # systemctl start httpd
  
then edit /etc/rc.conf (to start Apache at boot):  
+
then :  
 
    
 
    
   DAEMONS=(... httpd ...)
+
   # systemctl enable httpd
 
    
 
    
 
Then install the basic development tools (provides gcc, etc.)
 
Then install the basic development tools (provides gcc, etc.)
Line 309: Line 323:
  
 
   snd_bcm2835
 
   snd_bcm2835
 +
 +
Note: this step appears to be unnecessary with current versions of archlinux.
  
  
=== Install git, download and build ipscan ===
+
=== Install git, download and build IPscan ===
  
Then install git and download the ipscan source:
+
Then install git and download the IPscan source:
  
 
   # pacman -S git
 
   # pacman -S git
 
    
 
    
Then clone the ipscan source into a directory under your root user account:
+
Then clone the IPscan source into a directory under your root user account:
  
 
   [[email protected] ~]# git clone https://github.com/timsgit/ipscan ipscan
 
   [[email protected] ~]# git clone https://github.com/timsgit/ipscan ipscan
Line 330: Line 346:
  
 
    
 
    
Now follow the instructions in the [https://github.com/timsgit/ipscan/blob/master/README README file] within ipscan's github repository.
+
Now follow the instructions in the [https://github.com/timsgit/ipscan/blob/master/README README file] within IPscan's github repository.
  
 
It's necessary to change the Makefile to reflect your Apache server's  cgi-bin directory mapping:
 
It's necessary to change the Makefile to reflect your Apache server's  cgi-bin directory mapping:
Line 351: Line 367:
 
   </Directory>
 
   </Directory>
  
then modify your ipscan Makefile to reflect this:
+
then modify your IPscan Makefile to reflect this:
  
 
   # Install location for the CGI files
 
   # Install location for the CGI files
Line 362: Line 378:
 
   URIPATH=/cgi-bin6
 
   URIPATH=/cgi-bin6
  
Make sure you have created the /srv/http/cgi-bin6 directory (or whatever you have chosen) before attempting to build ipscan. Also make sure that your MySQL database is created following the instructions in the github repository. You will need to login to mysql using the root password you previously defined (above):
+
Make sure you have created the /srv/http/cgi-bin6 directory (or whatever you have chosen) before attempting to build IPscan. Also make sure that your MySQL database is created following the instructions in the github repository. You will need to login to mysql using the root password you previously defined (above):
  
 
   # mysql -u root -p
 
   # mysql -u root -p
Line 388: Line 404:
 
   #define MYSQL_TBLNAME "results"
 
   #define MYSQL_TBLNAME "results"
  
Then you should be able to make ipscan as '''root''' user and perform the install to transfer the necessary cgi files into your preferred cgi-bin directory:
+
Then you should be able to make IPscan as '''root''' user and perform the install to transfer the necessary cgi files into your preferred cgi-bin directory:
  
 
   # make && make install
 
   # make && make install
  
Prior to running the ipscan tester it is advisable to add a cron job which will execute the sqltidy.pl script to remove the completed scan results to protect your users' security and minimise the size of your database:
+
Prior to running the IPscan tester it is advisable to add a cron job which will execute the sqltidy.pl script to remove the completed scan results to protect your users' security and minimise the size of your database:
  
 
First install the necessary perl mysql data base interface modules:
 
First install the necessary perl mysql data base interface modules:
Line 402: Line 418:
 
   # /root/ipscan/sqltidy.pl
 
   # /root/ipscan/sqltidy.pl
 
    
 
    
And finally edit the root cron job to insert the line shown below (modified to reflect your ipscan source directory):
+
And finally edit the root cron job to insert the line shown below (modified to reflect your IPscan source directory):
  
 
   # crontab -e
 
   # crontab -e
Line 425: Line 441:
 
   # ps -ef |grep -i mysql
 
   # ps -ef |grep -i mysql
 
   root      392    1  0 Aug25 ?        00:00:00 /bin/sh /usr/bin/mysqld_safe --user=mysql
 
   root      392    1  0 Aug25 ?        00:00:00 /bin/sh /usr/bin/mysqld_safe --user=mysql
   mysql      688  392  0 Aug25 ?        01:47:48 /usr/bin/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib/mysql/plugin
+
   mysql      688  392  0 Aug25 ?        01:47:48 /usr/bin/mysqld --basedir=/usr --datadir=/var/lib/mysql ........
                                                   --user=mysql --log-error=/var/lib/mysql/alarmpi.err --pid-file=/var/lib/mysql/alarmpi.pid
+
                                                   --user=mysql --log-error=/var/lib/mysql/alarmpi.err .......
 
                                                   --socket=/var/run/mysqld/mysqld.sock --port=3306
 
                                                   --socket=/var/run/mysqld/mysqld.sock --port=3306
 
 
It is now worth checking that your Raspberry Pi has been correctly allocated an IPv6 address, using ifconfig:
 
 
  # ifconfig eth0
 
  eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
 
        inet AA.BB.C.DD  netmask 255.255.255.0  broadcast AA.BB.C.255
 
        inet6 '''2001:470:971f:3:ba27:ebff:fecc:dc7c'''  prefixlen 64  scopeid 0x0<global>
 
        inet6 fe80::ba27:ebff:fecc:dc7c  prefixlen 64  scopeid 0x20<link>
 
        ether b8:27:eb:cc:dc:7c  txqueuelen 1000  (Ethernet)
 
        RX packets 721789  bytes 103366589 (98.5 MiB)
 
        RX errors 0  dropped 48  overruns 0  frame 0
 
        TX packets 231210  bytes 130480722 (124.4 MiB)
 
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
 
  
  
 
Assuming that your Raspberry Pi has a valid IPv6 address and that your Apache and MySQL services are correctly running then you should be able to point a web browser to your cgi file:
 
Assuming that your Raspberry Pi has a valid IPv6 address and that your Apache and MySQL services are correctly running then you should be able to point a web browser to your cgi file:
  
e.g. towards '''http://[2001:470:971f:3:ba27:ebff:fecc:dc7c]/cgi-bin6/ipscan-txt.cgi'''
+
e.g. towards '''http://[2001:470:971f:6::3]/cgi-bin6/ipscan-txt.cgi'''
  
 
=== Restrict SSH Logins ===
 
=== Restrict SSH Logins ===
Line 460: Line 463:
  
  
This website publishes a [http://ipv6.chappell-family.com/html/privacy_policy.html Privacy Policy.] Continued use of this website implies your consent to the storage of data outlined in the policy.
+
This website publishes a Privacy Policy. Continued use of this website implies your consent to the use of data outlined in the policy.
  
  
 
----
 
----
 
 
<adsense>1</adsense>
 

Latest revision as of 16:40, 11 September 2016

How to make your own Raspberry Pi IPv6 firewall tester.

Suggested Reading

Before you begin please read the excellent Arch Linux Beginners' Guide.


Arch Linux Download and CF card creation

Fetch the Arch Linux download from RaspberryPi Downloads

If you are using win32 disk imager then please be aware that the image file needs to be extracted onto a local physical drive (e.g. C: ) rather than a network/remote drive.


Login, Change the root password and Create a plain user

Having logged in as root, then make sure you change the default password:

 # passwd
 

Then add a user, using a non-obvious username, e.g. PlnUsr456 : (follow the prompts)

 # useradd -m PlnUser456
 # passwd PlnUser456


Update your System and Install the Required Packages

Then update your system:

 # pacman -Syu
 

Which is likely to update pacman itself – just follow the prompts and once this is complete then re-attempt the complete upgrade:

 # pacman -Syu
 :: Synchronizing package databases...
  core is up to date
  extra is up to date
  community is up to date
  alarm is up to date
  aur is up to date
 :: Starting full system upgrade...
 resolving dependencies...
 looking for inter-conflicts...
 
 Proceed with installation? [Y/n]
 :: Retrieving packages from core...


Simplistic IPv6 Firewall

By default IPv6 support is disabled in later Arch Linux releases. To enable it, edit /boot/cmdline.txt and remove the ipv6.disable=1 statement from the beginning of the line.

Following this modification it is sensible to reboot your Raspberry Pi and check that it has been correctly allocated an IPv6 address, using ifconfig:

 # ifconfig eth0
 eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
       inet AA.BB.C.DD  netmask 255.255.255.0  broadcast AA.BB.C.255
       inet6 2001:470:971f:3:ba27:ebff:fecc:dc7c  prefixlen 64  scopeid 0x0<global>
       inet6 fe80::ba27:ebff:fecc:dc7c  prefixlen 64  scopeid 0x20<link>
       ether b8:27:eb:cc:dc:7c  txqueuelen 1000  (Ethernet)
       RX packets 721789  bytes 103366589 (98.5 MiB)
       RX errors 0  dropped 48  overruns 0  frame 0
       TX packets 231210  bytes 130480722 (124.4 MiB)
       TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

As a general starting point please read the ArchLinux IPtables documentation.

You will need to install the iptables modules and scripts using the following command:

 # pacman -S iptables

The following IPv6 firewall is a very simplistic example, where SLAAC IPv6 address allocation is in place. You will want to add additional source address and/or packet arrival rate checking on an internet-facing Raspberry Pi.

 *filter
 :INPUT DROP [0:0]
 :FORWARD DROP [0:0]
 :OUTPUT ACCEPT [0:0]
 :ICMP6FLTR - [0:0]
 :LOGIDROP - [0:0]
 -A LOGIDROP -m limit --limit 20/m --limit-burst 10 -j LOG --log-prefix "IPV6_INPUT_DROP " --log-ip-options --log-tcp-options --log-tcp-sequence
 -A LOGIDROP -j DROP
 #
 # ICMPv6 filter chain
 #
 # Allow ping of this host to aid debug - comment out if not required
 -A ICMP6FLTR -p ipv6-icmp --icmpv6-type echo-request -j ACCEPT
 -A ICMP6FLTR -m state -p ipv6-icmp --state ESTABLISHED,RELATED --icmpv6-type echo-reply -j ACCEPT
 -A ICMP6FLTR -m state -p ipv6-icmp --state ESTABLISHED,RELATED --icmpv6-type destination-unreachable -j ACCEPT
 -A ICMP6FLTR -m state -p ipv6-icmp --state ESTABLISHED,RELATED --icmpv6-type packet-too-big -j ACCEPT
 -A ICMP6FLTR -m state -p ipv6-icmp --state ESTABLISHED,RELATED --icmpv6-type unknown-header-type -j ACCEPT
 -A ICMP6FLTR -m state -p ipv6-icmp --state ESTABLISHED,RELATED --icmpv6-type unknown-option -j ACCEPT
 -A ICMP6FLTR -p ipv6-icmp --icmpv6-type ttl-zero-during-reassembly -j ACCEPT
 -A ICMP6FLTR -p ipv6-icmp --icmpv6-type bad-header -j ACCEPT
 #
 # Allow router advertisements to support SLAAC address allocation
 # ensure hop-limit (hl) is 255
 -A ICMP6FLTR -p ipv6-icmp --icmpv6-type router-advertisement --source fe80::/10 --match hl --hl-eq 255 -j ACCEPT
 -A ICMP6FLTR -p ipv6-icmp --icmpv6-type router-solicitation --match hl --hl-eq 255 -j ACCEPT
 #
 # Allow neighbour adv/sol so we can talk to our neighbouts (IPv6 ARP equivalent)
 # ensure hop-limit (hl) is 255
 -A ICMP6FLTR -p ipv6-icmp --icmpv6-type neighbour-advertisement --match hl --hl-eq 255 -j ACCEPT
 -A ICMP6FLTR -p ipv6-icmp --icmpv6-type neighbour-solicitation  --match hl --hl-eq 255 -j ACCEPT
 #
 # Allow inverse neighbour discovery solicitation (141) / advertisement (142)
 # ensure hop-limit (hl) is 255
 -A ICMP6FLTR -p ipv6-icmp --icmpv6-type 141 --match hl --hl-eq 255 -j ACCEPT
 -A ICMP6FLTR -p ipv6-icmp --icmpv6-type 142 --match hl --hl-eq 255 -j ACCEPT
 #
 # Allow certificate path solicitation (148) / advertisement (149)
 # ensure hop-limit (hl) is 255
 -A ICMP6FLTR -p ipv6-icmp --icmpv6-type 148 --match hl --hl-eq 255 -j ACCEPT
 -A ICMP6FLTR -p ipv6-icmp --icmpv6-type 149 --match hl --hl-eq 255 -j ACCEPT
 ##
 ## Allow ICMPv6 with link local addresses for multicast listener query (130), report (131), done (132) and report v2 (143)
 ## Likely unused, but uncomment if required
 #-A ICMP6FLTR -p ipv6-icmp --icmpv6-type 130 --source fe80::/10 -j ACCEPT
 #-A ICMP6FLTR -p ipv6-icmp --icmpv6-type 131 --source fe80::/10 -j ACCEPT
 #-A ICMP6FLTR -p ipv6-icmp --icmpv6-type 132 --source fe80::/10 -j ACCEPT
 #-A ICMP6FLTR -p ipv6-icmp --icmpv6-type 143 --source fe80::/10 -j ACCEPT
 ## Allow ICMPv6 with link local addresses and hop limit == 1 for multicast router advertisement (151), solicitation (152) and termination (153)
 #-A ICMP6FLTR -p ipv6-icmp --icmpv6-type 151 --source fe80::/10 --match hl --hl-eq 1 -j ACCEPT
 #-A ICMP6FLTR -p ipv6-icmp --icmpv6-type 152 --source fe80::/10 --match hl --hl-eq 1 -j ACCEPT
 #-A ICMP6FLTR -p ipv6-icmp --icmpv6-type 153 --source fe80::/10 --match hl --hl-eq 1 -j ACCEPT
 #
 # Drop everything else
 -A ICMP6FLTR -j LOGIDROP
 #
 # Main INPUT chain
 #
 # Allow all loopback traffic
 -A INPUT -i lo -j ACCEPT
 # Drop all routing header traffic (change if supporting mobile IPv6)
 -A INPUT -m rt --rt-type 0 -j LOGIDROP
 -A INPUT -m rt --rt-type 1 -j LOGIDROP
 -A INPUT -m rt --rt-type 2 -j LOGIDROP
 # Call ICMPv6 filter
 -A INPUT -p ipv6-icmp -j ICMP6FLTR
 # Allow all traffic related to, or part of an established stream
 -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
 # Allow SSH and HTTP traffic
 -A INPUT -p tcp --dport 22 -j ACCEPT
 -A INPUT -p tcp --dport 80 -j ACCEPT
 # Drop, but log, everything else
 -A INPUT -j LOGIDROP
 COMMIT  

Assuming your desired ruleset is stored in a file called simple_firewall6.rules then you can import the firewall rules using:

 # ip6tables-restore < simple_firewall6.rules

You can view the active firewall rules, and determine the number of packets being processed by each rule using:

 # ip6tables -v -n -L
 
 Chain INPUT (policy DROP 0 packets, 0 bytes)
  pkts bytes target     prot opt in     out     source               destination
     0     0 ACCEPT     all      lo     any     anywhere             anywhere
     6   480 LOGIDROP   all      any    any     anywhere             anywhere             rt type:0 segsleft:0
     0     0 LOGIDROP   all      any    any     anywhere             anywhere             rt type:1 segsleft:0
     0     0 LOGIDROP   all      any    any     anywhere             anywhere             rt type:2 segsleft:0
    94 14928 ICMP6FLTR  ipv6-icmp    any    any     anywhere             anywhere
   687 64315 ACCEPT     all      any    any     anywhere             anywhere             state RELATED,ESTABLISHED
    24  1892 ACCEPT     tcp      any    any     anywhere             anywhere             tcp dpt:ssh
     3   192 ACCEPT     tcp      any    any     anywhere             anywhere             tcp dpt:http
  2002  130K LOGIDROP   all      any    any     anywhere             anywhere
 
 Chain FORWARD (policy DROP 0 packets, 0 bytes)
  pkts bytes target     prot opt in     out     source               destination
 
 Chain OUTPUT (policy ACCEPT 680 packets, 336K bytes)
  pkts bytes target     prot opt in     out     source               destination
 
 Chain ICMP6FLTR (1 references)
  pkts bytes target     prot opt     in     out     source               destination
     1   176 ACCEPT     ipv6-icmp    any    any     anywhere             anywhere             ipv6-icmp echo-request
     0     0 ACCEPT     ipv6-icmp    any    any     anywhere             anywhere             state RELATED,ESTABLISHED ipv6-icmp echo-reply
     0     0 ACCEPT     ipv6-icmp    any    any     anywhere             anywhere             state RELATED,ESTABLISHED ipv6-icmp destination-unreachable
     0     0 ACCEPT     ipv6-icmp    any    any     anywhere             anywhere             state RELATED,ESTABLISHED ipv6-icmp packet-too-big
     0     0 ACCEPT     ipv6-icmp    any    any     anywhere             anywhere             state RELATED,ESTABLISHED ipv6-icmp unknown-header-type
     0     0 ACCEPT     ipv6-icmp    any    any     anywhere             anywhere             state RELATED,ESTABLISHED ipv6-icmp unknown-option
     0     0 ACCEPT     ipv6-icmp    any    any     anywhere             anywhere             ipv6-icmp ttl-zero-during-reassembly
     0     0 ACCEPT     ipv6-icmp    any    any     anywhere             anywhere             ipv6-icmp bad-header
    85 14280 ACCEPT     ipv6-icmp    any    any     anywhere             anywhere             ipv6-icmp router-advertisement HL match HL == 255
     0     0 ACCEPT     ipv6-icmp    any    any     anywhere             anywhere             ipv6-icmp router-solicitation HL match HL == 255
     0     0 ACCEPT     ipv6-icmp    any    any     anywhere             anywhere             ipv6-icmp neighbour-advertisement HL match HL == 255
     2   136 ACCEPT     ipv6-icmp    any    any     anywhere             anywhere             ipv6-icmp neighbour-solicitation HL match HL == 255
     0     0 ACCEPT     ipv6-icmp    any    any     anywhere             anywhere             ipv6-icmptype 141 HL match HL == 255
     0     0 ACCEPT     ipv6-icmp    any    any     anywhere             anywhere             ipv6-icmptype 142 HL match HL == 255
     0     0 ACCEPT     ipv6-icmp    any    any     anywhere             anywhere             ipv6-icmptype 148 HL match HL == 255
     0     0 ACCEPT     ipv6-icmp    any    any     anywhere             anywhere             ipv6-icmptype 149 HL match HL == 255
     6   336 LOGIDROP   all          any    any     anywhere             anywhere
 
 Chain LOGIDROP (5 references)
  pkts bytes target     prot opt in     out     source               destination
    12   784 LOG        all      any    any     anywhere             anywhere             limit: avg 20/min burst 10 LOG level warning tcp-sequence tcp-options ip-options prefix "IPV6_INPUT_DROP "
  2014  131K DROP       all      any    any     anywhere             anywhere
 
 

Once you're satisfied that the IPv6 firewall rules are performing correctly then they can be saved using the following command:

 # ip6tables-save >/etc/iptables/ip6tables.rules

Note that if you're also using IPv4 then don't forget to setup a similar IPv4 firewall ruleset. Again this example is only suitable for use in a trusted environment and needs further consideration for an internet facing machine.

 *filter
 :INPUT DROP [0:0]
 :FORWARD DROP [0:0]
 :OUTPUT ACCEPT [0:0]
 :LOGI4DROP - [0:0]
 -A LOGI4DROP -m limit --limit 10/m --limit-burst 5 -j LOG --log-prefix "IPV4_INPUT_DROP " --log-ip-options --log-tcp-options --log-tcp-sequence
 -A LOGI4DROP -j DROP
 # Allow all loopback traffic
 -A INPUT -i lo -j ACCEPT
 # Allow all traffic related to, or part of an established session
 -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
 # Allow ping of this host to aid debug - comment out if not required
 -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
 # Allow SSH and HTTP traffic
 -A INPUT -p tcp --dport 22 -j ACCEPT
 -A INPUT -p tcp --dport 80 -j ACCEPT
 # Allow DHCP related traffic
 -A INPUT -p udp --dport 67:68 -j ACCEPT
 # Drop everything else
 -A INPUT -j LOGI4DROP
 COMMIT


This time import can be performed using:

 # iptables-restore < simple_firewall.rules

Once you're happy with your IPv4 firewall then you can save the active rules using the following command:

 # iptables-save >/etc/iptables/iptables.rules

Note that it is import to check full functionality still exists with your firewall in place - this particularly applies to address allocation (e.g. DHCP and SLAAC) procedures which may mean that a misconfigured firewall makes your Raspberry Pi unreachable. This is one reason why it is useful to develop the two rulesets (IPv4 and IPv6) separately, since if you misconfigure one firewall and lose connectivity then you can fall back to the working protocol version to correct your mistake. Once you're happy that both firewall sets are correct then you can enable the services from boot:

 # systemctl enable ip6tables
 # systemctl enable iptables

You can check for dropped/logged packets (in the examples above logging is included for the IPv6 packet filter) using the following command:

 # tailf /var/log/iptables.log


Installing LAMP

Install LAMP by following the excellent Arch Linux LAMP guide.

 # pacman -S apache php php-apache mysql

Note: if you are running on a Model B version 1 then edit /etc/mysql/my.cnf to specify innodb_buffer_pool_size = 16M before attempting to start the service.

 # systemctl start mysqld 
 

Don't forget to add a MySQL password:

 # mysqladmin -u root password ‘password’
 # mysql -u root -p
 

Then issue the following command to start MySQL at boot:

  # systemctl enable mysqld
 

Read and follow the Apache section - I suggest that you adjust the default DocumentRoot directory by inserting an additional directory level (e.g. htdocs) under /srv/http so that you can place other directories at this same level without them all being under the Document root:

 /srv/http/
           htdocs/ - DocumentRoot directory for storage of your served web pages (e.g. index.php discussed below)
           cgi-bin6/ - directory for the IPscan cgi executables
 

If you follow this suggestion then don't forget to modify the DocumentRoot setting in the apache configuration file! Having followed the php installation guide then you'll also need to update php's base directory to match Apache inside /etc/php/php.ini:

 open_basedir = /srv/http/htdocs:/home/:/tmp/:/usr/share/pear/

And also define the timezone appropriately for your system:

 
  [Date]
  ; Defines the default timezone used by the date functions
  ; http://php.net/date.timezone
  date.timezone = "Europe/London"
  

Once Apache and PHP start successfully:

 # systemctl start httpd

then :

 # systemctl enable httpd
 

Then install the basic development tools (provides gcc, etc.)

 # pacman -S base-devel


And perl and the associated MySQL interface modules:

 # pacman -S perl-dbi perl-dbd-mysql


You may also wish to include spoken sound support:

 # pacman -S festival festival-english alsa-utils


And update your festivalrc file:

 # cat /root/.festivalrc
   
   (Parameter.set 'Audio_Command "/usr/bin/aplay -R1000 -q -c 1 -t raw -f s16 -r $SR $FILE")
   (Parameter.set 'Audio_Method 'Audio_Command)
 

And add a sound.conf file under /etc/modules-load.d to ensure the Broadcom sound module is loaded at boot. The file needs to contain a single statement shown below:

 # cat /etc/modules-load.d/sound.conf
 snd_bcm2835

Note: this step appears to be unnecessary with current versions of archlinux.


Install git, download and build IPscan

Then install git and download the IPscan source:

 # pacman -S git
 

Then clone the IPscan source into a directory under your root user account:

 [[email protected] ~]# git clone https://github.com/timsgit/ipscan ipscan
 Cloning into 'ipscan'...
 remote: Counting objects: 221, done.
 remote: Compressing objects: 100% (200/200), done.
 remote: Total 221 (delta 156), reused 85 (delta 20)
 Receiving objects: 100% (221/221), 102.97 KiB, done.
 Resolving deltas: 100% (156/156), done.
 [[email protected] ~]# ls ipscan
 COPYING  ipscan.c  ipscan_checks.c  ipscan_db.c  ipscan.h  ipscan_portlist.h  ipscan_web.c  Makefile  README  sqltidy.pl
 [[email protected] ~]#
 

Now follow the instructions in the README file within IPscan's github repository.

It's necessary to change the Makefile to reflect your Apache server's cgi-bin directory mapping:

Assuming your Apache configuration file (/etc/httpd/conf/httpd.conf) contains:

 DocumentRoot "/srv/http/htdocs"

and ...

 ScriptAlias /cgi-bin6/ "/srv/http/cgi-bin6/"

and ...

 <Directory "/srv/http/cgi-bin6">
   AllowOverride None
   Options +ExecCGI -Includes
   Order allow,deny
   Allow from all
 </Directory>

then modify your IPscan Makefile to reflect this:

 # Install location for the CGI files
 TARGETDIR=/srv/http/cgi-bin6
 
 # HTTP URI PATH by which external hosts will access the CGI files.
 # This may well be unrelated to the installation path if Apache is configured
 # to provide CGI access via an alias.
 # NB : the path should begin with a / but must NOT end with one ....
 URIPATH=/cgi-bin6

Make sure you have created the /srv/http/cgi-bin6 directory (or whatever you have chosen) before attempting to build IPscan. Also make sure that your MySQL database is created following the instructions in the github repository. You will need to login to mysql using the root password you previously defined (above):

 # mysql -u root -p
 
 mysql> create database ipscan;
      Query OK, 1 row affected (0.00 sec)
      
 mysql> create user 'ipscan-user'@'localhost' identified by 'ipscan-passwd';
      Query OK, 0 rows affected (0.01 sec)
 
 mysql> grant all privileges on ipscan.* to 'ipscan-user'@'localhost' identified by 'ipscan-passwd';
      Query OK, 0 rows affected (0.01 sec)
 
 mysql> exit
 

Modify the ipscan-user and ipscan-passwd entries to use your preferences (different to the ones that you chose for root!) and enter the same credentials into the ipscan.h include file:

 // MySQL database-related globals
 
 #define MYSQL_HOST "localhost"
 #define MYSQL_USER "ipscan-user"
 #define MYSQL_PASSWD "ipscan-passwd"
 #define MYSQL_DBNAME "ipscan"
 #define MYSQL_TBLNAME "results"

Then you should be able to make IPscan as root user and perform the install to transfer the necessary cgi files into your preferred cgi-bin directory:

 # make && make install

Prior to running the IPscan tester it is advisable to add a cron job which will execute the sqltidy.pl script to remove the completed scan results to protect your users' security and minimise the size of your database:

First install the necessary perl mysql data base interface modules:

 # pacman -S perl-dbi-mysql perl-mysql  
 

Then modify the MySQL related entries in the sqltidy.pl script to match your chosen user, password, etc. and then ensure that the script runs standalone without any perl errors:

 # /root/ipscan/sqltidy.pl
 

And finally edit the root cron job to insert the line shown below (modified to reflect your IPscan source directory):

 # crontab -e
 

You may wish to move sqltidy.pl to another location, but ensure its permissions prevent ordinary users from reading or executing the file:

 */5 * * * * /root/ipscan/sqltidy.pl 2>&1

Check your Services and IPv6 address allocation

Now it is suggested that you check your Apache service is running using lsof:

 # pacman -S lsof
 
 # lsof -i -n -P |grep http
 httpd     712     root    4u  IPv6   1457      0t0  TCP *:80 (LISTEN)
 httpd   16107     http    4u  IPv6   1457      0t0  TCP *:80 (LISTEN)
 ...

And for MySQL:

 # ps -ef |grep -i mysql
 root       392     1  0 Aug25 ?        00:00:00 /bin/sh /usr/bin/mysqld_safe --user=mysql
 mysql      688   392  0 Aug25 ?        01:47:48 /usr/bin/mysqld --basedir=/usr --datadir=/var/lib/mysql ........
                                                 --user=mysql --log-error=/var/lib/mysql/alarmpi.err .......
                                                 --socket=/var/run/mysqld/mysqld.sock --port=3306


Assuming that your Raspberry Pi has a valid IPv6 address and that your Apache and MySQL services are correctly running then you should be able to point a web browser to your cgi file:

e.g. towards http://[2001:470:971f:6::3]/cgi-bin6/ipscan-txt.cgi

Restrict SSH Logins

In general it is recommended that you apply all the standard SSH hardening approaches. You can also restrict logins to your newly created plain user (above) with the addition of the following line to your ssh configuration file (/etc/ssh/sshd_config). I'd also recommend that you choose an username which isn't a simple shortening of your own name:

 AllowUsers PlnUsr456


Example PHP landing page

An example PHP landing page can be found by following the link Raspberry_Pi_IPv6_firewall_tester_landingpage.


This website publishes a Privacy Policy. Continued use of this website implies your consent to the use of data outlined in the policy.