Setting up a debian router
During some digital security seminars, there was the need to set up an internal network with internet access for the participants. An old laptop was used to act as the router between the lan and the internet. Since there was no wired internet connection available, the laptop-router was configured to be able to connect to the internet either via a wifi or through GSM network.
The laptop turned router used was named tool. It will thus be referred as such in the rest of this article.
Note: Tool had no hard drive. The installation was done on a USB stick, using a 32 bit debian installation. That gives the advantage of it being portable, so that practically any laptop could take tool's role, with minimal if any configuration.
Περιεχόμενα
Task[επεξεργασία]
Setting up tool so that it will:
- Have its ethernet interface (eth0) connected to the LAN.
- Connect to the internet using WIFI or GSM.
- Route traffic between LAN and internet.
- Act as firewall and perform necessary NAT.
- Act as a DHCP server for the LAN.
- Act as a DNS server for the LAN.
- Operate a simple anonymous read-only ftp server for sharing files inside the LAN.
- Act as a transparent HTTP cache proxy (not implemented yet).
Installing and preparing the operating system on tool[επεξεργασία]
The operating system of choice was Debian Wheezy, 32-bit, running a 3.2+ Linux kernel. (Initially Debian Squeeze was tried, but failed to recognize some wifi and GSM cards). I did a bare installation, no desktop environment, only standard system utilities.
hostname: toole domain: lan
Setting up the repos[επεξεργασία]
In addition to 'free', 'contrib' and 'non-free' repos were enabled in /etc/apt/sources.list in order to access all necessary firmware for the large variety of wifi cards.
apt-get update apt-get upgrade
Installing firmware[επεξεργασία]
apt-get install firmware-linux* firmware-atheros firmware-iwlwifi firmware-ralink firmware-realtek reboot
Services/Software[επεξεργασία]
- Tool will be remotely managed via SSH (openssh-server)
- Tool will be a firewall (iptables)
- Tool will be a DHCP server and caching DNS proxy (dnsmasq)
- Tool will connect to WIFI and GSM networks (network-manager)
- Tool will be an FTP server (proftpd)
- Some participants didn't have ftp clients, so a web server was set up to share the ftp files (apache2)
- Python3 is needed for a script.
- NTP for network time auto configuration.
- resolvconf will be installed to manage editing of /etc/resolv.conf
apt-get install openssh-server dnsmasq ntp network-manager proftpd apache2 python3 resolvconf
SSH server[επεξεργασία]
/etc/ssh/sshd_config can be edited to only allow pubkey auth or enforce listening only on LAN address. The latter is optional because it will be enforced through iptables.
Setting up networking[επεξεργασία]
eth0[επεξεργασία]
Edit /etc/network/interfaces as following:
# the loopback interface auto lo iface lo inet loopback # setting up the LAN interface (eth0) auto eth0 iface eth0 inet static address 192.168.69.1 netmask 255.255.255.0 # make internal wifi card unmanageable by network manager, will use wlan1 instead which is an external stronger one iface wlan0 inet static
network-manager[επεξεργασία]
We need network-manager to manage wireless and GSM. Network-manager is usually used by desktop environments. It also has a cli interface called nmcli.
However, nmcli doesn't support the creation of new connections. In order to create a new connection, one option is to first create it in a linux machine running some network-manager interface and then transfer the configuration file to tool. Another is to attempt to write the conf file by hand. The third is to use a script.
Network-manager connection information is stored in separate files inside /etc/NetworkManager/system-connections .
What I did is:
- Use a script to create new wifi network connections.
- Transfer the GSM connection file that was initially created through a nm gui of another computer.
The GSM connection[επεξεργασία]
A vodafone pay on demand internet packet was used. I created the connection file in a nm gui in another computer. The file was stored as /etc/NetworkManager/system-connections/VodOD , owned by root:root with 600 perms.
[connection] id=Vodafone Mobile Broadband On Demand 1 uuid=ef8677ec-0b70-4dca-a75f-308047a8dfd2 type=gsm autoconnect=false [gsm] number=*99# password-flags=1 apn=web.session pin-flags=1 [ipv4] method=auto [serial] baud=115200
the script[επεξεργασία]
I stole a python3 script from checkbox and edited a bit as follows:
#!/usr/bin/env python3 import sys import os import time from subprocess import ( check_call, check_output, CalledProcessError, ) from uuid import uuid4 from argparse import ArgumentParser CONNECTIONS_PATH = '/etc/NetworkManager/system-connections/' def connection_section(ssid, uuid): if not uuid: uuid = uuid4() connection = """ [connection] id=%s uuid=%s type=802-11-wireless autoconnect=false """ % (ssid, uuid) wireless = """ [802-11-wireless] ssid=%s mode=infrastructure""" % (ssid) return connection + wireless def security_section(security, key): # Add security field to 802-11-wireless section wireless_security = """ security=802-11-wireless-security [802-11-wireless-security] """ if security.lower() == 'wpa': wireless_security += """ key-mgmt=wpa-psk auth-alg=open psk=%s """ % key elif security.lower() == 'wep': wireless_security += """ key-mgmt=none wep-key=%s """ % key return wireless_security def ip_sections(): ip = """ [ipv4] method=auto [ipv6] method=auto """ return ip def block_until_created(connection, retries, interval): while retries > 0: nmcli_con_list = check_output(['nmcli', 'con', 'list'], universal_newlines=True) if connection in nmcli_con_list: print("Connection %s registered" % connection) break time.sleep(interval) retries = retries - 1 if retries <= 0: print("Failed to register %s." % connection, file=sys.stderr) sys.exit(1) else: try: nmcli_con_up = check_call(['nmcli', 'con', 'up', 'id', connection]) print("Connection %s activated." % connection) except CalledProcessError as error: print("Failed to activate %s." % connection, file=sys.stderr) sys.exit(error.returncode) def main(): parser = ArgumentParser() parser.add_argument('ssid', help="The SSID to connect to.") parser.add_argument('-S', '--security', help=("The type of security to be used " "by the connection. One of wpa and wep. " "No security will be used " "if nothing is specified.")) parser.add_argument('-K', '--key', help="The encryption key required by the router.") parser.add_argument('-U', '--uuid', help="""The uuid to assign to the connection for use by NetworkManager. One will be generated if not specified here.""") parser.add_argument('-R', '--retries', help="""The number of times to attempt bringing up the connection until it is confirmed as active.""", default=5) parser.add_argument('-I', '--interval', help=("The time to wait between attempts to detect the " "registration of the connection."), default=2) args = parser.parse_args() connection_info = connection_section(args.ssid, args.uuid) if args.security: # Set security options if not args.key: print("You need to specify a key using --key " "if using wireless security.", file=sys.stderr) sys.exit(1) connection_info += security_section(args.security, args.key) elif args.key: print("You specified an encryption key " "but did not give a security type using --security.", file=sys.stderr) sys.exit(1) try: check_call(['rfkill','unblock','wlan','wifi']) #except CalledProcessError: except: print("Could not unblock wireless devices with rfkill.", file=sys.stderr) # Don't fail the script if unblock didn't work though connection_info += ip_sections() # NetworkManager replaces forward-slashes in SSIDs with asterisks connection_file = args.ssid.replace('/', '*') try: connection_file = open(CONNECTIONS_PATH + connection_file, 'w') connection_file.write(connection_info) os.fchmod(connection_file.fileno(), 0o600) connection_file.close() except IOError: print("Can't write to " + CONNECTIONS_PATH + args.ssid + ". Is this command being run as root?", file=sys.stderr) sys.exit(1) block_until_created(args.ssid, args.retries, args.interval) if __name__ == "__main__": main()
I saved that script as create-wireless-connection.py and did a chmod u+x .
setting up the firewall[επεξεργασία]
su touch /etc/network/if-pre-up.d/iptables chmod 755 /etc/network/if-pre-up.d/iptables
Add the following to /etc/network/if-pre-up.d/iptables
#!/bin/bash ethif=eth0 wlanif=wlan1 pppif=ppp0 ## disabling IP forwarding echo 0 > /proc/sys/net/ipv4/ip_forward ## flushing iptables chains=`cat /proc/net/ip_tables_names` for i in $chains; do iptables -t $i -F iptables -t $i -X iptables -t $i -Z done ## setting default policy for INPUT,OUTPUT,FORWARD iptables -P INPUT DROP iptables -P OUTPUT ACCEPT iptables -P FORWARD DROP ## setting up NAT iptables -t nat -A POSTROUTING -o $wlanif -j MASQUERADE iptables -t nat -A POSTROUTING -o $pppif -j MASQUERADE ## FORWARD chain # allow forwarding coming from lan interface and subnet iptables -A FORWARD -i $ethif -j ACCEPT # allow forwarding of established incoming traffic from outside iptables -A FORWARD -i $wlanif -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A FORWARD -i $pppif -m state --state ESTABLISHED,RELATED -j ACCEPT ## INPUT chain # allow loopback traffic iptables -A INPUT -i lo -j ACCEPT # allow internal traffic iptables -A INPUT -i $ethif -j ACCEPT # allow established incoming traffic from outside iptables -A INPUT -i $wlanif -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A INPUT -i $pppif -m state --state ESTABLISHED,RELATED -j ACCEPT ## enabling IP forwarding echo 1 > /proc/sys/net/ipv4/ip_forward
This script will be called upon activation of eth0 during boot.
ppp0 is the interface that will be created by the gsm modem. In this scenario eth0 is connected to LAN, wlan1 to wifi's, but these can be changed in the configuration section in the beginning of the script.
setting up dnsmasq[επεξεργασία]
dnsmasq is a DHCP server and dns forwarder. My /etc/dnsmasq.conf file without the comments:
domain-needed local=/lan/ interface=eth0 interface=lo dhcp-range=192.168.69.100,192.168.69.199,12h
Using tool[επεξεργασία]
Boot tool and either log in locally or via ssh.
To connect via ssh just connect to tool's eth0 port (directly or through preconfigured switch/ap) and obtain address from DHCP, then ssh tool.
Use nmcli to manage connections. Read the man page. Some usefull commands:
- nmcli nm : network-manager status
- nmcli nm wifi [on|off] : see wifi status, optionally enable/disable
- nmcli nm wwan [on|off] : see wwan (mobile) status, optionally enable/disable
- nmcli dev : list available network devices (anything defined in /etc/network/interfaces is unmanageable by nm)
- nmcli con : list available connections
- nmcli con status : list active connections (doesn't include connections configured in /etc/network/interfaces)
- nmcli con up id MyConnection
Try using -p, or perhaps even doing:
alias nmcli="nmcli -p"
Network manager has the following preference:
- wired
- wireless
- mobile
In our case, wired isn't handled by nm. So nm will route traffic via wifi if available, mobile eitherwise.
Connect to GSM[επεξεργασία]
GSM connection conf file must be manually created or transfer. In my case it was called VodOD. To enable it
nmcli nm wwan on nmcli con up id VodOD
Then check with
nmcli con status
If GSM needs a password to be enabled (internet on demand with prepayed cards), you should be able to do it from any computer connected to LAN.
Connect to new wireless network[επεξεργασία]
Use
iwlist wlan1 scan
or
nm-tool
(try also nm-tool | grep Strength) to list available networks. Use create-wireless-connection.py to create connection. Example:
./create-wireless-connection.py -S wpa -K mykey myssid
- -S wpa for wpa or wpa2
- -S wep for wep
- no -S for unencrypted wifi
Connection will be created and set up. Edit config file in /etc/NetworkManager/system-connections and remove autoconnect=false if you need it to connect automatically.