Linux Router with VPN on a Raspberry Pi: Difference between revisions

From Alpine Linux
No edit summary
No edit summary
Line 1: Line 1:
[[Category:Networking]]
== Rationale ==
== Rationale ==


Line 10: Line 8:


For wireless a separate access point was purchased [http://wiki.openwrt.org/toh/ubiquiti/unifi Ubiquiti UniFi AP] because it contains a Atheros AR9287 which is supported by [https://wireless.wiki.kernel.org/en/users/drivers/ath9k ath9k] and I was keen to avoid blob drivers.
For wireless a separate access point was purchased [http://wiki.openwrt.org/toh/ubiquiti/unifi Ubiquiti UniFi AP] because it contains a Atheros AR9287 which is supported by [https://wireless.wiki.kernel.org/en/users/drivers/ath9k ath9k] and I was keen to avoid blob drivers.
== Modem in full bridge mode ==
Your modem will need to be configured in "full bridge mode". The method for doing this varies depending on the interface on your device and is out of the scope of this tutorial.
The modem I am using is a [http://www.cisco.com/c/en/us/products/routers/877-integrated-services-router-isr/index.html Cisco 877 Integrated Services Router]. It has no web interface and is controlled over SSH. I have put the configuration file up here because it took me some time to figure out the IOS commands to get the device configured in this way.
When sshing into this device with a recent version of ssh you may need to use this command:
  ssh -o HostKeyAlgorithms=ssh-rsa,ssh-dss -o KexAlgorithms=diffie-hellman-group1-sha1 \
-o Ciphers=aes128-cbc,3des-cbc -o MACs=hmac-md5,hmac-sha1 admin@192.168.0.1
As there is a bug [https://bugzilla.redhat.com/show_bug.cgi?id=1026430 here] and [https://bugs.launchpad.net/ubuntu/+source/openssh/+bug/1287222 here] with new versions of OpenSSH and Cisco's old sshd.
=== Configuration of a Cisco 877 ADSL Modem ===
<pre>!
version 12.4
no service pad
service timestamps debug datetime msec
service timestamps log datetime msec
service password-encryption
!
hostname <HOSTNAME>
!
boot-start-marker
boot-end-marker
!
logging message-counter syslog
logging buffered 4096 informational
enable secret 5 <SECRET>
!
aaa new-model
!
!
aaa authentication login default local
aaa authentication login local_auth local
aaa authorization exec default local none
!
!
aaa session-id common
!
!
dot11 syslog
ip source-route
no ip routing
!
!
!
!
no ip cef
ip domain name <DOMAIN NAME>
no ipv6 cef
!
multilink bundle-name authenticated
!
!
!
username admin privilege 15 secret 5 <SECRET>
username USER privilege 15 password 7 <SECRET>
!
!
!
archive
log config
  hidekeys
!
!
ip ssh version 2
ip scp server enable
!
bridge irb
!
!
interface ATM0
no ip address
no ip route-cache
no atm ilmi-keepalive
pvc 8/35
  encapsulation aal5snap
!
bridge-group 1
!
interface FastEthernet0
!
interface FastEthernet1
!
interface FastEthernet2
!
interface FastEthernet3
!
interface Dot11Radio0
no ip address
no ip route-cache
shutdown
speed basic-1.0 basic-2.0 basic-5.5 6.0 9.0 basic-11.0 12.0 18.0 24.0 36.0 48.0 54.0
station-role root
!
interface Vlan1
no ip address
no ip route-cache
bridge-group 1
!
interface BVI1
ip address 192.168.0.1 255.255.255.252
no ip route-cache
!
ip default-gateway 192.168.0.2
ip default-network 192.168.0.0
ip forward-protocol nd
no ip http server
no ip http secure-server
!
!
!
ip access-list standard SSH_ACCESS
!This is a list of the addresses you want to allow
permit <IP>
permit <IP>
!
!
!
!
!
!
control-plane
!
bridge 1 protocol ieee
bridge 1 route ip
banner login
Authorized access only!
Disconnect IMMEDIATELY if you are not an authorized user!
!
line con 0
no modem enable
line aux 0
line vty 0 4
access-class SSH_ACCESS in
authorization exec local_author
login authentication login_local
transport input ssh
!
scheduler max-task-time 5000
end</pre>
Besides changing the obvious things such as the hostname, domain name, and permitted IPs, you'll also need to verify the ATM0 settings match your ISP's configuration. Specifically: "pvc 8/35" and "encapsulation aal5snap" works for me but may not for you. You will also need to generate the passwords and replace all the instances of <SECRET>.
=== Generating the passwords ===
==== Secret 5 Password ====
You can generate the hash for the "secret 5" passwords with this OpenSSL command:
    openssl passwd -salt `openssl rand -base64 3` -1 "<YOUR PASSWORD>"
Put the output in <SECRET>
==== Secret 7 Password ====
To encrypt the secret 7 password you can use this [https://www.m00nie.com/2011/09/cisco-type-7-password-decryption-and-encryption-with-perl/ perl script] thanks to m00nie.
<pre>#!/usr/bin/perl
# Cisco (type 7) password tool from www.m00nie.com :D
# Will either decrypt a _TYPE 7_ password from a cisco device
# or will encrypt a string so that it can be used in a cisco
# device.
#
# I made this code to learn more Perl and just out of interest
# about the type 7 "encryption". The decryption code is already
# and from a mailing list. The original header from that is below.
#
# Credits for original code and description hobbit@avian.org,
# SPHiXe, .mudge et al. and for John Bashinski <jbash@CISCO.COM>
# for Cisco IOS password encryption facts.
#
# Use for any malice or illegal purposes strictly prohibited!
#
@xlat = ( 0x64, 0x73, 0x66, 0x64, 0x3b, 0x6b, 0x66, 0x6f, 0x41,
          0x2c, 0x2e, 0x69, 0x79, 0x65, 0x77, 0x72, 0x6b, 0x6c,
          0x64, 0x4a, 0x4b, 0x44, 0x48, 0x53 , 0x55, 0x42 );
$loop = 0;
while ($loop == 0) {
print "\n\n***************************************************************\n";
print "*    Cisco (type 7) password tool from www.m00nie.com :D      *\n";
print "* Use for any malice or illegal purposes strictly prohibited! *\n";
        print "***************************************************************\n\n";
print "1. Decrypt a password\n";
print "2. Encrypt plain text\n";
print "3. Quit\n\n";
print "Pick either 1, 2 or 3: ";
chomp ($choice = <STDIN>);
if ( $choice == 1 ) {
decrypt()
} elsif ( $choice == 2) {
encrypt()
} elsif ($choice == 3) {
exit
} else {
print "$choice is not a valid option\n";
}
}
sub decrypt {
print "Enter the encrypted password: ";
chomp ($epass = <STDIN>);
        if (!(length($epass) & 1)) {
                $ep = $epass;
$dpass = "";
                ($s, $e) = ($ep =~ /^(..)(.+)/);
                for ($i = 0; $i < length($e); $i+=2){
                  $dpass .= sprintf "%c",hex(substr($e,$i,2))^$xlat[$s++];
}
            }
print "\nEncrypted pass was: $epass\n";
print "Decrypted pass is: $dpass\n";
}
sub encrypt {
print "Enter the string to encrypt:\n";
chomp ($ptext = <STDIN>);
$pt = $ptext;
$etext = "";
$n = 2;
$etext .=  sprintf("%.2o", $n);
for ($k = 0; $k < length($pt); $k+=1){
$tmp = ord(substr($pt,$k,1))^$xlat[$n++];
$etext .= sprintf("%.2X", $tmp);
}
print "\nPlain string was: $ptext\n";
print "Encrypted string is: $etext\n";
}
# eof</pre>

Revision as of 18:12, 5 June 2015

Rationale

This guide demonstrates how to set up a Raspberry Pi as an Open Source Linux router with a VPN tunnel.

I had decided against re-flashing a consumer router with an embedded firmware like OpenWrt, DD-WRT or Tomato because these devices were not intended to run alternate firmware.

Support for devices varies significantly depending on which one you have - sometimes down to the revision of the router. Integrating wireless into the device creates significant driver compatibility issues as certain wireless chipsets have better support than others (eg Broadcom and Marvell).

For wireless a separate access point was purchased Ubiquiti UniFi AP because it contains a Atheros AR9287 which is supported by ath9k and I was keen to avoid blob drivers.

Modem in full bridge mode

Your modem will need to be configured in "full bridge mode". The method for doing this varies depending on the interface on your device and is out of the scope of this tutorial.

The modem I am using is a Cisco 877 Integrated Services Router. It has no web interface and is controlled over SSH. I have put the configuration file up here because it took me some time to figure out the IOS commands to get the device configured in this way.

When sshing into this device with a recent version of ssh you may need to use this command:

  ssh -o HostKeyAlgorithms=ssh-rsa,ssh-dss -o KexAlgorithms=diffie-hellman-group1-sha1 \
-o Ciphers=aes128-cbc,3des-cbc -o MACs=hmac-md5,hmac-sha1 admin@192.168.0.1

As there is a bug here and here with new versions of OpenSSH and Cisco's old sshd.

Configuration of a Cisco 877 ADSL Modem

!
version 12.4
no service pad
service timestamps debug datetime msec
service timestamps log datetime msec
service password-encryption
!
hostname <HOSTNAME>
!
boot-start-marker
boot-end-marker
!
logging message-counter syslog
logging buffered 4096 informational
enable secret 5 <SECRET>
!
aaa new-model
!
!
aaa authentication login default local
aaa authentication login local_auth local
aaa authorization exec default local none 
!
!
aaa session-id common
!
!
dot11 syslog
ip source-route
no ip routing
!
!
!
!
no ip cef
ip domain name <DOMAIN NAME>
no ipv6 cef
!
multilink bundle-name authenticated
!
!
!
username admin privilege 15 secret 5 <SECRET>
username USER privilege 15 password 7 <SECRET>
! 
!
!
archive
 log config
  hidekeys
!
!
ip ssh version 2
ip scp server enable
!
bridge irb
!
!
interface ATM0
 no ip address
 no ip route-cache
 no atm ilmi-keepalive
 pvc 8/35 
  encapsulation aal5snap
 !
 bridge-group 1
!
interface FastEthernet0
!
interface FastEthernet1
!
interface FastEthernet2
!
interface FastEthernet3
!
interface Dot11Radio0
 no ip address
 no ip route-cache
 shutdown
 speed basic-1.0 basic-2.0 basic-5.5 6.0 9.0 basic-11.0 12.0 18.0 24.0 36.0 48.0 54.0
 station-role root
!
interface Vlan1
 no ip address
 no ip route-cache
 bridge-group 1
!
interface BVI1
 ip address 192.168.0.1 255.255.255.252
 no ip route-cache
!
ip default-gateway 192.168.0.2
ip default-network 192.168.0.0
ip forward-protocol nd
no ip http server
no ip http secure-server
!
!
!
ip access-list standard SSH_ACCESS
!This is a list of the addresses you want to allow
 permit <IP>
 permit <IP>
!
!
!
!
!
!
control-plane
!
bridge 1 protocol ieee
bridge 1 route ip
banner login 
Authorized access only!
Disconnect IMMEDIATELY if you are not an authorized user!


!
line con 0
 no modem enable
line aux 0
line vty 0 4
 access-class SSH_ACCESS in
 authorization exec local_author
 login authentication login_local
 transport input ssh
!
scheduler max-task-time 5000
end

Besides changing the obvious things such as the hostname, domain name, and permitted IPs, you'll also need to verify the ATM0 settings match your ISP's configuration. Specifically: "pvc 8/35" and "encapsulation aal5snap" works for me but may not for you. You will also need to generate the passwords and replace all the instances of <SECRET>.

Generating the passwords

Secret 5 Password

You can generate the hash for the "secret 5" passwords with this OpenSSL command:

   openssl passwd -salt `openssl rand -base64 3` -1 "<YOUR PASSWORD>"

Put the output in <SECRET>

Secret 7 Password

To encrypt the secret 7 password you can use this perl script thanks to m00nie.

#!/usr/bin/perl 
# Cisco (type 7) password tool from www.m00nie.com :D 
# Will either decrypt a _TYPE 7_ password from a cisco device
# or will encrypt a string so that it can be used in a cisco
# device. 
# 
# I made this code to learn more Perl and just out of interest 
# about the type 7 "encryption". The decryption code is already 
# and from a mailing list. The original header from that is below.
#
# Credits for original code and description hobbit@avian.org,
# SPHiXe, .mudge et al. and for John Bashinski <jbash@CISCO.COM>
# for Cisco IOS password encryption facts.
#
# Use for any malice or illegal purposes strictly prohibited!
#

@xlat = ( 0x64, 0x73, 0x66, 0x64, 0x3b, 0x6b, 0x66, 0x6f, 0x41,
          0x2c, 0x2e, 0x69, 0x79, 0x65, 0x77, 0x72, 0x6b, 0x6c,
          0x64, 0x4a, 0x4b, 0x44, 0x48, 0x53 , 0x55, 0x42 );

$loop = 0;
while ($loop == 0) {
	print "\n\n***************************************************************\n";
	print "*    Cisco (type 7) password tool from www.m00nie.com :D      *\n";
	print "* Use for any malice or illegal purposes strictly prohibited! *\n";
        print "***************************************************************\n\n";
	print "1. Decrypt a password\n";
	print "2. Encrypt plain text\n";
	print "3. Quit\n\n";
	print "Pick either 1, 2 or 3: ";
	chomp ($choice = <STDIN>);
	if ( $choice == 1 ) {
		decrypt()
	} elsif ( $choice == 2) {
		encrypt()
	} elsif ($choice == 3) {
		exit
	} else {
		print "$choice is not a valid option\n";
	}		
}

sub decrypt {
print "Enter the encrypted password: ";
chomp ($epass = <STDIN>);

        	if (!(length($epass) & 1)) {
                	$ep = $epass; 
			$dpass = "";
                	($s, $e) = ($ep =~ /^(..)(.+)/);
                	for ($i = 0; $i < length($e); $i+=2){
                  		$dpass .= sprintf "%c",hex(substr($e,$i,2))^$xlat[$s++];
			}
            	}
		print "\nEncrypted pass was: $epass\n";
		print "Decrypted pass is: $dpass\n";
}

sub encrypt {
	print "Enter the string to encrypt:\n";
	chomp ($ptext = <STDIN>);
	$pt = $ptext;
	$etext = "";
	$n = 2;
	$etext .=  sprintf("%.2o", $n);
	for ($k = 0; $k < length($pt); $k+=1){
		$tmp = ord(substr($pt,$k,1))^$xlat[$n++];
		$etext .= sprintf("%.2X", $tmp);
	} 
	print "\nPlain string was: $ptext\n";
	print "Encrypted string is: $etext\n";
}
# eof